Skip to content

Commit 1fbfeef

Browse files
Improve performance (#34)
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
1 parent 5d1dad0 commit 1fbfeef

File tree

8 files changed

+44
-46
lines changed

8 files changed

+44
-46
lines changed

browser.js

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,4 @@
1-
/* eslint-env browser */
2-
3-
const bufferToHex = buffer => {
4-
const view = new DataView(buffer);
5-
6-
let hexCodes = '';
7-
for (let index = 0; index < view.byteLength; index += 4) {
8-
hexCodes += view.getUint32(index).toString(16).padStart(8, '0');
9-
}
10-
11-
return hexCodes;
12-
};
1+
import {bufferToHex} from './utilities.js';
132

143
const create = algorithm => async (buffer, {outputFormat = 'hex'} = {}) => {
154
if (typeof buffer === 'string') {

index.js

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import {Buffer} from 'node:buffer';
21
import {Worker} from 'node:worker_threads';
32
import crypto from 'node:crypto';
3+
import {bufferToHex} from './utilities.js';
44

55
let create = algorithm => async (buffer, {outputFormat = 'hex'} = {}) => {
66
const hash = crypto.createHash(algorithm);
@@ -52,24 +52,11 @@ if (Worker !== undefined) {
5252
});
5353

5454
create = algorithm => async (source, {outputFormat = 'hex'} = {}) => {
55-
let buffer;
56-
if (typeof source === 'string') {
57-
// Saving one copy operation by writing string to buffer right away and then transfering buffer
58-
buffer = new ArrayBuffer(Buffer.byteLength(source, 'utf8'));
59-
Buffer.from(buffer).write(source, 'utf8');
60-
} else {
61-
const finalSource = source instanceof ArrayBuffer ? new Uint8Array(source) : source;
62-
63-
// Creating a copy of buffer at call time, will be transfered later
64-
buffer = finalSource.buffer.slice(0); // eslint-disable-line unicorn/prefer-spread
65-
}
55+
const {buffer} = typeof source === 'string' ? new TextEncoder().encode(source) : (source instanceof ArrayBuffer ? new Uint8Array(source) : source);
6656

67-
const result = await taskWorker({algorithm, buffer}, [buffer]);
68-
if (outputFormat === 'hex') {
69-
return Buffer.from(result).toString('hex');
70-
}
57+
const hash = await taskWorker({algorithm, buffer}, [buffer]);
7158

72-
return result;
59+
return outputFormat === 'hex' ? bufferToHex(hash) : hash;
7360
};
7461
}
7562

index.test-d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import {expectType} from 'tsd';
2-
import {sha1, sha256, sha384, sha512} from './index.js';
2+
import {
3+
sha1,
4+
sha256,
5+
sha384,
6+
sha512,
7+
} from './index.js';
38

49
expectType<Promise<string>>(sha1('🦄'));
510
expectType<Promise<ArrayBuffer>>(sha1('🦄', {outputFormat: 'buffer'}));

package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"index.js",
2828
"index.d.ts",
2929
"browser.js",
30-
"thread.js"
30+
"thread.js",
31+
"utilities.js"
3132
],
3233
"keywords": [
3334
"crypto",
@@ -43,10 +44,10 @@
4344
"browser"
4445
],
4546
"devDependencies": {
46-
"@sindresorhus/is": "^6.0.1",
47-
"ava": "^5.3.1",
47+
"@sindresorhus/is": "^7.0.0",
48+
"ava": "^6.1.3",
4849
"hash.js": "^1.1.7",
49-
"tsd": "^0.29.0",
50-
"xo": "^0.56.0"
50+
"tsd": "^0.31.1",
51+
"xo": "^0.59.2"
5152
}
5253
}

test-browser.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
/* eslint-env jasmine */
22
import hashjs from 'hash.js';
33
import is from '@sindresorhus/is';
4-
import {sha1, sha256, sha384, sha512} from './browser.js';
4+
import {
5+
sha1,
6+
sha256,
7+
sha384,
8+
sha512,
9+
} from './browser.js';
510

611
const fixture = 'foo bar baz';
712

test.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
import {Buffer} from 'node:buffer';
21
import test from 'ava';
32
import hashjs from 'hash.js';
43
import is from '@sindresorhus/is';
5-
import {sha1, sha256, sha384, sha512} from './index.js';
4+
import {
5+
sha1,
6+
sha256,
7+
sha384,
8+
sha512,
9+
} from './index.js';
610

711
const fixture = 'foo bar baz';
812

@@ -33,8 +37,7 @@ test('buffer input', async t => {
3337

3438
test('buffer input - ArrayBuffer', async t => {
3539
const fixture = 'x';
36-
const fixtureBuffer = new ArrayBuffer(Buffer.byteLength(fixture, 'utf8'));
37-
Buffer.from(fixtureBuffer).write(fixture, 'utf8');
40+
const fixtureBuffer = new TextEncoder().encode(fixture).buffer;
3841
t.is(await sha1(fixture), await sha1(fixtureBuffer));
3942
});
4043

thread.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import {Buffer} from 'node:buffer';
21
import crypto from 'node:crypto';
32
import {parentPort} from 'node:worker_threads';
43

5-
parentPort.on('message', message => {
6-
const {algorithm, buffer} = message.value;
4+
parentPort.on('message', ({id, value: {algorithm, buffer}}) => {
75
const hash = crypto.createHash(algorithm);
8-
hash.update(Buffer.from(buffer));
9-
const arrayBuffer = hash.digest().buffer;
6+
hash.update(new DataView(buffer));
7+
const value = hash.digest().buffer;
108
// Transfering buffer here for consistency, but considering buffer size it might be faster to just leave it for copying, needs perf test
11-
parentPort.postMessage({id: message.id, value: arrayBuffer}, [arrayBuffer]);
9+
parentPort.postMessage({id, value}, [value]);
1210
});

utilities.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export const bufferToHex = buffer => {
2+
const view = new DataView(buffer);
3+
4+
let hexCodes = '';
5+
for (let index = 0; index < view.byteLength; index += 4) {
6+
hexCodes += view.getUint32(index).toString(16).padStart(8, '0');
7+
}
8+
9+
return hexCodes;
10+
};

0 commit comments

Comments
 (0)