We needed to generate hash of graphql queries on one of our high throughput services and were vary of adding another crypto call because node. Luckily, the internet had some great resources for benchmarking and hashing.

Starting with these two as inspiration:

I wanted to run my own tests because we were hashing significantly larger strings, the worst case around 60kb.

I adjusted the script from the medium article to include blake2 in the following manner.

const Benchmark = require('benchmark');
const suite = new Benchmark.Suite;
const hash = require('crypto').createHash;
const blake2 = require('blake2');
const scenarios = [
  { alg: 'blake2', digest: 'base64' },
  { alg: 'blake2', digest: 'hex' },
  { alg: 'md5', digest: 'hex' },
  { alg: 'md5', digest: 'base64' },
  { alg: 'sha1', digest: 'hex' },
  { alg: 'sha1', digest: 'base64' },
  { alg: 'sha256', digest: 'hex' },
  { alg: 'sha256', digest: 'base64' },

];

const fs = require('fs')

fs.readFile('query.graphql', 'utf8' , (err, data) => {
  if (err) {
    console.error(err)
    return
  }
  const bufferData = Buffer.from(data);
  for (const { alg, digest } of scenarios) {
    suite.add(`${alg}-${digest}`, () => {
       if (alg === 'blake2') {
        blake2.createHash('blake2b', {digestLength: 16}).update(bufferData).digest().toString(digest);

       } else {
        hash(alg).update(data).digest(digest)

       }

    }
    );
  }
  suite.on('cycle', function(event) {
    console.log(String(event.target));
  })
  .on('complete', function() {
    console.log('Fastest is ' + this.filter('fastest').map('name'));
  })
  .run();
})

Here are the results from running on my MacBook Pro (15-inch Mid 2018) (geekbench)

blake2-base64 x 14,672 ops/sec ±1.26% (86 runs sampled)
blake2-hex x 14,205 ops/sec ±3.46% (82 runs sampled)
md5-hex x 11,685 ops/sec ±2.32% (87 runs sampled)
md5-base64 x 11,059 ops/sec ±3.15% (85 runs sampled)
sha1-hex x 15,355 ops/sec ±3.41% (86 runs sampled)
sha1-base64 x 14,266 ops/sec ±4.74% (77 runs sampled)
sha256-hex x 7,679 ops/sec ±1.43% (87 runs sampled)
sha256-base64 x 7,704 ops/sec ±1.49% (85 runs sampled)

Here are the (somewhat surprising) results on a AWS EC2 c5.large instance (geekbench). This stackoverflow was useful for getting things installed.

blake2-base64 x 9,494 ops/sec ±0.44% (95 runs sampled)
blake2-hex x 9,502 ops/sec ±0.47% (96 runs sampled)
md5-hex x 10,592 ops/sec ±0.33% (96 runs sampled)
md5-base64 x 10,619 ops/sec ±0.23% (99 runs sampled)
sha1-hex x 14,854 ops/sec ±0.10% (98 runs sampled)
sha1-base64 x 14,889 ops/sec ±0.08% (98 runs sampled)
sha256-hex x 6,975 ops/sec ±0.02% (99 runs sampled)
sha256-base64 x 6,969 ops/sec ±0.14% (100 runs sampled)

I’m going to stick with sha1-hex for my application. I have no idea why blake2 is slower on ec2, but perhaps that a mystery a reader can enlighten me on in the comments.

Last modified: October 28, 2021

Author

Comments

Write a Reply or Comment

Your email address will not be published.