Skip to content

Commit

Permalink
Merge 81aba23 into 7ab3567
Browse files Browse the repository at this point in the history
  • Loading branch information
ashi009 committed Oct 4, 2019
2 parents 7ab3567 + 81aba23 commit 6a03286
Show file tree
Hide file tree
Showing 13 changed files with 1,896 additions and 1,210 deletions.
8 changes: 3 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
language: node_js
node_js:
- "5"
- "4"
- "0.12"
- "0.11"
- "0.10"
- "12"
- "10"
after_success: yarn run coverage
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# fast-crc32c [![NPM version](https://badge.fury.io/js/fast-crc32c.svg)](http://badge.fury.io/js/fast-crc32c) [![Build Status](https://travis-ci.org/ashi009/node-fast-crc32c.svg?branch=master)](https://travis-ci.org/ashi009/node-fast-crc32c) [![Dependency Status](https://david-dm.org/ashi009/node-fast-crc32c.svg)](https://david-dm.org/ashi009/node-fast-crc32c)
# fast-crc32c [![NPM version](https://badge.fury.io/js/fast-crc32c.svg)](http://badge.fury.io/js/fast-crc32c) [![Build Status](https://travis-ci.org/ashi009/node-fast-crc32c.svg?branch=master)](https://travis-ci.org/ashi009/node-fast-crc32c) [![Dependency Status](https://david-dm.org/ashi009/node-fast-crc32c.svg)](https://david-dm.org/ashi009/node-fast-crc32c) [![Coverage Status](https://coveralls.io/repos/github/ashi009/node-fast-crc32c/badge.svg?branch=master)](https://coveralls.io/github/ashi009/node-fast-crc32c?branch=master)

fast-crc32c is a CRC-32C algorithm implementation for node.js, which uses
hardware acceleration (via [voxer/sse4_crc32][sse4_crc32] by Anand Suresh), and
Expand All @@ -12,15 +12,15 @@ register width (64bit) instead of CRC-32's 8bit.
When using hardware acceleration, CRC-32C is about 7x ~ 9x faster than software
implemented CRC-32C.

**Benchmark**
### Benchmark

The 3 tested implementations are:

- **sse4\_crc32c** Hardware accelerated CRC-32C from [sse4_crc32][sse4_crc32]
- **js_crc32c** Javascript implemented CRC-32C
- **js_crc32** Javascript implemented CRC-32 from [buffer-crc32][buffer-crc32]

```
```shell
$ npm run-script benchmark

> fast-crc32c@1.0.2 benchmark /Users/xshi/Projects/node-fast-crc32c
Expand Down
33 changes: 17 additions & 16 deletions benchmark/index.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
var util = require('util');
var Benchtable = require('benchtable');
const util = require('util');
const Benchtable = require('benchtable');

var suite = new Benchtable();
const suite = new Benchtable();

var kTesters = [{
const kTesters = [{
name: 'sse4_crc32c_hw',
calculate: require('sse4_crc32').sse42_crc
calculate: require('sse4_crc32').sse42_crc,
}, {
name: 'sse4_crc32c_sw',
calculate: require('sse4_crc32').table_crc
calculate: require('sse4_crc32').table_crc,
}, {
name: 'js_crc32c',
calculate: require('../impls/js_crc32c').calculate
calculate: require('../impls/js_crc32c').calculate,
}, {
name: 'js_crc32',
calculate: require('buffer-crc32').unsigned
calculate: require('buffer-crc32').unsigned,
}];

kTesters.forEach(function(tester) {
suite.addFunction(tester.name, function(inputs) {
for (var i = 0; i < inputs.length; i++)
for (let i = 0; i < inputs.length; i++) {
tester.calculate(inputs[i]);
}
});
});

var k1kBuffer = [generateBuffer(1024)];
var k4kBuffers = generateBuffers(4096);
const k1kBuffer = [generateBuffer(1024)];
const k4kBuffers = generateBuffers(4096);

suite.addInput('1024B', [k1kBuffer]);
suite.addInput(util.format('%dB, avg %dB', k4kBuffers.totalSize, parseInt(k4kBuffers.averageSize)),
Expand All @@ -40,10 +41,10 @@ suite.on('cycle', function(event) {
.run();

function generateBuffers(maxBufferSize) {
var bufs = [];
const bufs = [];
bufs.totalSize = 0;
for (var i = 0; i < maxBufferSize * 2; i++) {
var size = parseInt(Math.random() * maxBufferSize);
for (let i = 0; i < maxBufferSize * 2; i++) {
const size = parseInt(Math.random() * maxBufferSize);
bufs.push(generateBuffer(size));
bufs.totalSize += size;
}
Expand All @@ -52,8 +53,8 @@ function generateBuffers(maxBufferSize) {
}

function generateBuffer(size) {
var buf = new Buffer(size);
for (var i = 0; i < size; i++)
const buf = new Buffer(size);
for (let i = 0; i < size; i++)
buf[i] = parseInt(Math.random() * 256);
return buf;
}
48 changes: 23 additions & 25 deletions generate-tests.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,53 @@
var rndstr = require('random-string');
var fs = require('fs');
var crc32 = require('sse4_crc32').calculate;
const rndstr = require('random-string');
const fs = require('fs');
const crc32 = require('sse4_crc32').calculate;

var tests = {
const tests = {
string: {
tests: []
cases: [],
},
buffer: {
tests: []
cases: [],
}
};

for (var i = 0; i < 10; i++) {
var str = rndstr({
for (let i = 0; i < 10; i++) {
const str = rndstr({
length: 1024,
// numeric: true,
// letters: true,
// // special: true
});
tests.string.tests.push({
tests.string.cases.push({
input: str,
output: crc32(str)
});
}

for (var i = 0; i < 10; i++) {
var buf = new Buffer(1024);
for (var j = 0; j < 1024; j++)
for (let i = 0; i < 10; i++) {
const buf = Buffer.alloc(1024);
for (let j = 0; j < 1024; j++) {
buf.writeUInt8(parseInt(Math.random() * 256), j);
tests.buffer.tests.push({
}
tests.buffer.cases.push({
input: buf,
output: crc32(buf)
});
}

var strs = ['', '\0'];
const strs = ['', '\0'];
strs.forEach(function(str) {
tests.string.tests.push({
tests.string.cases.push({
input: str,
output: crc32(str)
output: crc32(str),
});
var buf = new Buffer(str);
tests.buffer.tests.push({
const buf = Buffer.from(str, 'utf-8');
tests.buffer.cases.push({
input: buf,
output: crc32(buf)
output: crc32(buf),
});
});

for (var type in tests) {
tests[type].output = tests[type].tests.reduce(function(prev, test) {
return crc32(test.input, prev);
for (const type in tests) {
tests[type].output = tests[type].cases.reduce(function(prev, cs) {
return crc32(cs.input, prev);
}, 0);
}

Expand Down
26 changes: 13 additions & 13 deletions impls/js_crc32c.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* './pycrc.py --model=crc-32c --generate c --algorithm=table-driven'
*/

var kCRCTable = new Int32Array([
var kCRCTable = Int32Array.of(
0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4,
0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
Expand Down Expand Up @@ -68,18 +68,18 @@ var kCRCTable = new Int32Array([
0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81,
0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e,
0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,
0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351
]);

function calculate(buf, initial) {
if (!Buffer.isBuffer(buf))
buf = new Buffer(buf);
var crc = (initial | 0) ^ -1;
for (var i = 0; i < buf.length; i++)
crc = kCRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
return (crc ^ -1) >>> 0;
}
0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351,
);

module.exports = {
calculate: calculate
calculate(buf, initial) {
if (!Buffer.isBuffer(buf)) {
buf = Buffer.from(buf);
}
let crc = (initial | 0) ^ -1;
for (let i = 0; i < buf.length; i++) {
crc = kCRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
}
return (crc ^ -1) >>> 0;
},
};
2 changes: 1 addition & 1 deletion impls/sse4_crc32c.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var sse4_crc32 = require('sse4_crc32');

module.exports = {
calculate: sse4_crc32.calculate
calculate: sse4_crc32.calculate,
};
36 changes: 18 additions & 18 deletions loader.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
var fs = require('fs');

module.exports = (function(loaders) {

var impls = [
'./impls/sse4_crc32c_hw',
'./impls/sse4_crc32c_sw',
'./impls/js_crc32c'
const impls = [
'./impls/sse4_crc32c',
'./impls/js_crc32c',
];

for (var i = 0; i < impls.length; i++) {
try {
var crc32 = require(impls[i]);
if (crc32.calculate("The quick brown fox jumps over the lazy dog") == 0x22620404)
return crc32;
} catch(e) {
module.exports = (() => {
for (const impl of impls) {
try {
const crc32 = require(impl);
if (crc32.calculate('The quick brown fox jumps over the lazy dog') === 0x22620404) {
return crc32;
}
} catch(e) {
// ignore the error and try next implementation.
}
}
}

throw new Error('Failed to find available CRC-32C implementation.');

return {
calculate() {
throw new Error('no CRC-32C implementation is available');
},
};
})();

0 comments on commit 6a03286

Please sign in to comment.