Skip to content

Commit

Permalink
Improve string performance
Browse files Browse the repository at this point in the history
  • Loading branch information
dougwilson committed Oct 14, 2014
1 parent f667d66 commit 69166b9
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 35 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
unreleased
==========

* Improve string performance
* Slightly improve speed for weak ETags over 1KB

1.4.0 / 2014-09-21
Expand Down
40 changes: 20 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ $ npm run-script bench
3 tests completed.
4 tests completed.

buffer - strong x 426,717 ops/sec ±1.34% (181 runs sampled)
* buffer - weak x 1,081,596 ops/sec ±0.32% (196 runs sampled)
string - strong x 235,880 ops/sec ±1.01% (190 runs sampled)
string - weak x 373,234 ops/sec ±0.87% (192 runs sampled)
buffer - strong x 425,962 ops/sec ±1.21% (186 runs sampled)
* buffer - weak x 1,094,538 ops/sec ±0.35% (197 runs sampled)
string - strong x 437,636 ops/sec ±1.31% (183 runs sampled)
string - weak x 316,978 ops/sec ±1.55% (188 runs sampled)

> node benchmark/body1-1kb.js

Expand All @@ -77,10 +77,10 @@ $ npm run-script bench
3 tests completed.
4 tests completed.

buffer - strong x 274,188 ops/sec ±1.17% (192 runs sampled)
* buffer - weak x 298,451 ops/sec ±0.49% (194 runs sampled)
string - strong x 157,331 ops/sec ±2.12% (186 runs sampled)
string - weak x 169,242 ops/sec ±1.51% (188 runs sampled)
buffer - strong x 278,712 ops/sec ±1.00% (193 runs sampled)
* buffer - weak x 300,008 ops/sec ±0.30% (196 runs sampled)
string - strong x 276,016 ops/sec ±1.13% (188 runs sampled)
string - weak x 166,522 ops/sec ±1.47% (192 runs sampled)

> node benchmark/body2-5kb.js

Expand All @@ -91,10 +91,10 @@ $ npm run-script bench
3 tests completed.
4 tests completed.

buffer - strong x 102,624 ops/sec ±0.93% (193 runs sampled)
* buffer - weak x 104,696 ops/sec ±1.17% (190 runs sampled)
string - strong x 59,097 ops/sec ±3.93% (186 runs sampled)
string - weak x 59,202 ops/sec ±4.01% (185 runs sampled)
buffer - strong x 105,233 ops/sec ±0.65% (195 runs sampled)
* buffer - weak x 108,091 ops/sec ±0.81% (194 runs sampled)
string - strong x 102,725 ops/sec ±0.80% (192 runs sampled)
string - weak x 102,649 ops/sec ±0.85% (193 runs sampled)

> node benchmark/body3-10kb.js

Expand All @@ -105,10 +105,10 @@ $ npm run-script bench
3 tests completed.
4 tests completed.

buffer - strong x 54,768 ops/sec ±1.43% (188 runs sampled)
* buffer - weak x 57,393 ops/sec ±1.10% (192 runs sampled)
string - strong x 36,597 ops/sec ±3.81% (179 runs sampled)
string - weak x 35,525 ops/sec ±3.82% (186 runs sampled)
buffer - strong x 59,673 ops/sec ±0.46% (195 runs sampled)
* buffer - weak x 61,525 ops/sec ±0.54% (194 runs sampled)
string - strong x 57,557 ops/sec ±0.62% (194 runs sampled)
string - weak x 58,627 ops/sec ±0.59% (195 runs sampled)

> node benchmark/body4-100kb.js

Expand All @@ -119,10 +119,10 @@ $ npm run-script bench
3 tests completed.
4 tests completed.

* buffer - strong x 6,243 ops/sec ±0.84% (194 runs sampled)
* buffer - weak x 6,312 ops/sec ±0.95% (193 runs sampled)
string - strong x 4,984 ops/sec ±2.21% (191 runs sampled)
string - weak x 5,068 ops/sec ±2.32% (190 runs sampled)
buffer - strong x 6,733 ops/sec ±0.26% (196 runs sampled)
* buffer - weak x 6,920 ops/sec ±0.40% (197 runs sampled)
string - strong x 6,344 ops/sec ±0.47% (193 runs sampled)
string - weak x 6,236 ops/sec ±1.03% (189 runs sampled)
```

## License
Expand Down
31 changes: 16 additions & 15 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ function etag(entity, options) {
throw new TypeError('argument entity is required')
}

var isBuffer = Buffer.isBuffer(entity)
var isStats = isstats(entity)
var weak = options && typeof options.weak === 'boolean'
? options.weak
Expand All @@ -52,16 +51,13 @@ function etag(entity, options) {
return stattag(entity, weak)
}

if (!isBuffer && typeof entity !== 'string') {
if (typeof entity !== 'string' && !Buffer.isBuffer(entity)) {
throw new TypeError('argument entity must be string, Buffer, or fs.Stats')
}

var buf = !isBuffer
? new Buffer(entity, 'utf8')
: entity
var hash = weak
? weakhash(buf)
: stronghash(buf)
? weakhash(entity)
: stronghash(entity)

return weak
? 'W/"' + hash + '"'
Expand Down Expand Up @@ -131,15 +127,15 @@ function stattag(stat, weak) {
* @api private
*/

function stronghash(buf) {
if (buf.length === 0) {
function stronghash(entity) {
if (entity.length === 0) {
// fast-path empty
return '1B2M2Y8AsgTpgAmY7PhCfg=='
}

return crypto
.createHash('md5')
.update(buf)
.update(entity, 'utf8')
.digest('base64')
}

Expand All @@ -151,20 +147,25 @@ function stronghash(buf) {
* @api private
*/

function weakhash(buf) {
if (buf.length === 0) {
function weakhash(entity) {
if (entity.length === 0) {
// fast-path empty
return '0-0'
}

if (buf.length <= crc32threshold) {
var len = typeof entity === 'string'
? Buffer.byteLength(entity, 'utf8')
: entity.length

if (len <= crc32threshold) {
// crc32 plus length when it's fast
return buf.length.toString(16) + '-' + crc(buf).toString(16)
// crc(str) only accepts utf-8 encoding
return len.toString(16) + '-' + crc(entity).toString(16)
}

// use md4 for long strings
return crypto
.createHash('md4')
.update(buf)
.update(entity, 'utf8')
.digest('base64')
}

0 comments on commit 69166b9

Please sign in to comment.