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