Created
May 18, 2017 09:45
-
-
Save markcode/a526d8889f8f9fa5cc293d7507b2d515 to your computer and use it in GitHub Desktop.
Benchmark speed and standard deviation between md5 (2 bytes of) and crc for a hash key.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
// | |
// Benchmark speed and standard deviation between md5 (2 bytes of) and crc for a hash key. | |
// | |
// Version: 0.0.1 | |
// Author: Mark W. B. Ashcroft (mark [at] fluidecho [dot] com) | |
// License: MIT or Apache 2.0. | |
// | |
// Copyright (c) 2017 Mark W. B. Ashcroft. | |
// Copyright (c) 2017 FluidEcho. | |
// | |
//const preview = require('preview')('md5vscrc'); | |
const crypto = require('crypto'); | |
const crc = require('crc'); | |
const Sse4Crc32 = require("sse4_crc32"); | |
const stats = require('stats-lite'); | |
// NOTES: | |
// crc32c (hardware) is the fastest and has the best SD, crc16-CCITT however is as good as md5 | |
// and twice as fast. crc16-CCITT is in JS, so will recomend that. crc16 has poorer SD for | |
// sequential keys. | |
var x = 1000000; | |
md5(x, function() { | |
crc16(x, function() { | |
crc32(x); | |
}); | |
}); | |
// MD5 | |
function md5(x, cb) { | |
var slices = new Array(65536); | |
slices.fill(0); | |
var start = Date.now(); | |
for ( var y = 0; y < x; y++ ) { | |
//var key = process.hrtime()[1].toString(); | |
//var key = crypto.randomBytes(10); | |
//var key = y.toString(); | |
var key = ""; | |
for( var i=0; i < 3; i++ ) { | |
key += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(Math.floor(Math.random() * 62)); | |
} | |
key += y.toString(); | |
var hased_key = crypto.createHash('md5').update(key).digest().slice(0, 2); | |
// preview('hased_key: ', hased_key); | |
var SLICE = ((hased_key[0] << 8) + (hased_key[1])) >>> 0; | |
//preview('SLICE: ', SLICE); | |
slices[SLICE]++; | |
} | |
report('MD5', start, slices); | |
return cb(); | |
} | |
// CRC16-ccitt | |
function crc16(x, cb) { | |
var slices = new Array(65536); | |
slices.fill(0); | |
var start = Date.now(); | |
for ( var y = 0; y < x; y++ ) { | |
//var key = process.hrtime()[1].toString(); | |
//var key = crypto.randomBytes(10); | |
//var key = y.toString(); | |
var key = ""; | |
for( var i=0; i < 3; i++ ) { | |
key += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(Math.floor(Math.random() * 62)); | |
} | |
key += y.toString(); | |
var SLICE = crc.crc16ccitt(key); // crc16modbus and crc16 are less consitant | |
var hashed_key = new Buffer(2); | |
hashed_key[0] = SLICE >>> 8 & 0xff; | |
hashed_key[1] = SLICE & 0xff; | |
//preview('hased_key: ', hased_key); | |
//var SLICE = ((hased_key[0] << 8) + (hased_key[1])) >>> 0; | |
//preview('SLICE: ', SLICE); | |
slices[SLICE]++; | |
} | |
report('CRC16', start, slices); | |
return cb(); | |
} | |
// CRC32C | |
function crc32(x) { | |
var slices = new Array(65536); | |
slices.fill(0); | |
var start = Date.now(); | |
for ( var y = 0; y < x; y++ ) { | |
//var key = process.hrtime()[1].toString(); | |
//var key = crypto.randomBytes(10); | |
//var key = y.toString(); | |
var key = ""; | |
for( var i=0; i < 3; i++ ) { | |
key += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(Math.floor(Math.random() * 62)); | |
} | |
key += y.toString(); | |
var crc = Sse4Crc32.calculate(key); | |
//preview('crc32', crc32); | |
var hashed_key = new Buffer(2); | |
hashed_key[0] = crc >>> 8 & 0xff; | |
hashed_key[1] = crc & 0xff; | |
var SLICE = ((hashed_key[0] << 8) + (hashed_key[1])) >>> 0; | |
//preview('hased_key: ', hased_key); | |
//var SLICE = ((hased_key[0] << 8) + (hased_key[1])) >>> 0; | |
//preview('SLICE: ', SLICE); | |
slices[SLICE]++; | |
} | |
report('CRC32', start, slices); | |
} | |
function report(testing, start, slices) { | |
let ms = Date.now() - start; | |
console.log(testing + ', completed in: ' + ms + ' ms'); | |
console.log('slices: ',slices); | |
console.log("sum: %s", stats.sum(slices)) | |
console.log("mean: %s", stats.mean(slices)) | |
console.log("median: %s", stats.median(slices)) | |
console.log("mode: %s", stats.mode(slices)) | |
console.log("variance: %s", stats.variance(slices)) | |
console.log("standard deviation: %s", stats.stdev(slices)) | |
console.log("85th percentile: %s", stats.percentile(slices, 0.85)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment