mirror of https://github.com/lukechilds/node.git
Browse Source
Adds additional `targetStart`, `targetEnd`, `sourceStart, and `sourceEnd` arguments to `Buffer.prototype.compare` to allow comparison of sub-ranges of two Buffers without requiring Buffer.prototype.slice() Fixes: https://github.com/nodejs/node/issues/521 PR-URL: https://github.com/nodejs/node/pull/5880 Reviewed-By: Trevor Norris <trev.norris@gmail.com>process-exit-stdio-flushing
James M Snell
9 years ago
5 changed files with 248 additions and 27 deletions
@ -0,0 +1,58 @@ |
|||||
|
'use strict'; |
||||
|
const common = require('../common.js'); |
||||
|
const v8 = require('v8'); |
||||
|
|
||||
|
const bench = common.createBenchmark(main, { |
||||
|
method: ['offset', 'slice'], |
||||
|
size: [16, 512, 1024, 4096, 16386], |
||||
|
millions: [1] |
||||
|
}); |
||||
|
|
||||
|
function compareUsingSlice(b0, b1, len, iter) { |
||||
|
|
||||
|
// Force optimization before starting the benchmark
|
||||
|
Buffer.compare(b0.slice(1, len), b1.slice(1, len)); |
||||
|
v8.setFlagsFromString('--allow_natives_syntax'); |
||||
|
eval('%OptimizeFunctionOnNextCall(Buffer.compare)'); |
||||
|
eval('%OptimizeFunctionOnNextCall(b0.slice)'); |
||||
|
eval('%OptimizeFunctionOnNextCall(b1.slice)'); |
||||
|
Buffer.compare(b0.slice(1, len), b1.slice(1, len)); |
||||
|
doCompareUsingSlice(b0, b1, len, iter); |
||||
|
} |
||||
|
|
||||
|
function doCompareUsingSlice(b0, b1, len, iter) { |
||||
|
var i; |
||||
|
bench.start(); |
||||
|
for (i = 0; i < iter; i++) |
||||
|
Buffer.compare(b0.slice(1, len), b1.slice(1, len)); |
||||
|
bench.end(iter / 1e6); |
||||
|
} |
||||
|
|
||||
|
function compareUsingOffset(b0, b1, len, iter) { |
||||
|
len = len + 1; |
||||
|
// Force optimization before starting the benchmark
|
||||
|
b0.compare(b1, 1, len, 1, len); |
||||
|
v8.setFlagsFromString('--allow_natives_syntax'); |
||||
|
eval('%OptimizeFunctionOnNextCall(b0.compare)'); |
||||
|
b0.compare(b1, 1, len, 1, len); |
||||
|
doCompareUsingOffset(b0, b1, len, iter); |
||||
|
} |
||||
|
|
||||
|
function doCompareUsingOffset(b0, b1, len, iter) { |
||||
|
var i; |
||||
|
bench.start(); |
||||
|
for (i = 0; i < iter; i++) |
||||
|
b0.compare(b1, 1, len, 1, len); |
||||
|
bench.end(iter / 1e6); |
||||
|
} |
||||
|
|
||||
|
function main(conf) { |
||||
|
const iter = (conf.millions >>> 0) * 1e6; |
||||
|
const size = (conf.size >>> 0); |
||||
|
const method = conf.method === 'slice' ? |
||||
|
compareUsingSlice : compareUsingOffset; |
||||
|
method(Buffer.alloc(size, 'a'), |
||||
|
Buffer.alloc(size, 'b'), |
||||
|
size >> 1, |
||||
|
iter); |
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
require('../common'); |
||||
|
const assert = require('assert'); |
||||
|
|
||||
|
const a = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]); |
||||
|
const b = Buffer.from([5, 6, 7, 8, 9, 0, 1, 2, 3, 4]); |
||||
|
|
||||
|
assert.equal(-1, a.compare(b)); |
||||
|
|
||||
|
// Equivalent to a.compare(b).
|
||||
|
assert.equal(-1, a.compare(b, 0)); |
||||
|
assert.equal(-1, a.compare(b, '0')); |
||||
|
|
||||
|
// Equivalent to a.compare(b).
|
||||
|
assert.equal(-1, a.compare(b, 0, undefined, 0)); |
||||
|
|
||||
|
// Zero-length targer, return 1
|
||||
|
assert.equal(1, a.compare(b, 0, 0, 0)); |
||||
|
assert.equal(1, a.compare(b, '0', '0', '0')); |
||||
|
|
||||
|
// Equivalent to Buffer.compare(a, b.slice(6, 10))
|
||||
|
assert.equal(1, a.compare(b, 6, 10)); |
||||
|
|
||||
|
// Zero-length source, return -1
|
||||
|
assert.equal(-1, a.compare(b, 6, 10, 0, 0)); |
||||
|
|
||||
|
// Equivalent to Buffer.compare(a.slice(4), b.slice(0, 5))
|
||||
|
assert.equal(1, a.compare(b, 0, 5, 4)); |
||||
|
|
||||
|
// Equivalent to Buffer.compare(a.slice(1), b.slice(5))
|
||||
|
assert.equal(1, a.compare(b, 5, undefined, 1)); |
||||
|
|
||||
|
// Equivalent to Buffer.compare(a.slice(2), b.slice(2, 4))
|
||||
|
assert.equal(-1, a.compare(b, 2, 4, 2)); |
||||
|
|
||||
|
// Equivalent to Buffer.compare(a.slice(4), b.slice(0, 7))
|
||||
|
assert.equal(-1, a.compare(b, 0, 7, 4)); |
||||
|
|
||||
|
// Equivalent to Buffer.compare(a.slice(4, 6), b.slice(0, 7));
|
||||
|
assert.equal(-1, a.compare(b, 0, 7, 4, 6)); |
||||
|
|
||||
|
// zero length target
|
||||
|
assert.equal(1, a.compare(b, 0, null)); |
||||
|
|
||||
|
// coerces to targetEnd == 5
|
||||
|
assert.equal(-1, a.compare(b, 0, {valueOf: () => 5})); |
||||
|
|
||||
|
// zero length target
|
||||
|
assert.equal(1, a.compare(b, Infinity, -Infinity)); |
||||
|
|
||||
|
// zero length target because default for targetEnd <= targetSource
|
||||
|
assert.equal(1, a.compare(b, '0xff')); |
||||
|
|
||||
|
const oor = /out of range index/; |
||||
|
|
||||
|
assert.throws(() => a.compare(b, 0, 100, 0), oor); |
||||
|
assert.throws(() => a.compare(b, 0, 1, 0, 100), oor); |
||||
|
assert.throws(() => a.compare(b, -1), oor); |
||||
|
assert.throws(() => a.compare(b, 0, '0xff'), oor); |
||||
|
assert.throws(() => a.compare(b, 0, Infinity), oor); |
||||
|
assert.throws(() => a.compare(b, -Infinity, Infinity), oor); |
||||
|
assert.throws(() => a.compare(), /Argument must be a Buffer/); |
Loading…
Reference in new issue