Skip to content

Commit d13aba8

Browse files
mscdexitaloacasas
authored andcommitted
buffer: improve compare() performance
PR-URL: #10927 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 6549bc2 commit d13aba8

File tree

2 files changed

+87
-25
lines changed

2 files changed

+87
-25
lines changed

benchmark/buffers/buffer-compare-instance-method.js

+63-9
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,80 @@ const v8 = require('v8');
44

55
const bench = common.createBenchmark(main, {
66
size: [16, 512, 1024, 4096, 16386],
7+
args: [1, 2, 3, 4, 5],
78
millions: [1]
89
});
910

1011
function main(conf) {
1112
const iter = (conf.millions >>> 0) * 1e6;
1213
const size = (conf.size >>> 0);
13-
const b0 = new Buffer(size).fill('a');
14-
const b1 = new Buffer(size).fill('a');
14+
const args = (conf.args >>> 0);
15+
const b0 = Buffer.alloc(size, 'a');
16+
const b1 = Buffer.alloc(size, 'a');
17+
const b0Len = b0.length;
18+
const b1Len = b1.length;
19+
var i;
1520

1621
b1[size - 1] = 'b'.charCodeAt(0);
1722

1823
// Force optimization before starting the benchmark
19-
b0.compare(b1);
24+
switch (args) {
25+
case 2:
26+
b0.compare(b1, 0);
27+
break;
28+
case 3:
29+
b0.compare(b1, 0, b1Len);
30+
break;
31+
case 4:
32+
b0.compare(b1, 0, b1Len, 0);
33+
break;
34+
case 5:
35+
b0.compare(b1, 0, b1Len, 0, b0Len);
36+
break;
37+
default:
38+
b0.compare(b1);
39+
}
2040
v8.setFlagsFromString('--allow_natives_syntax');
2141
eval('%OptimizeFunctionOnNextCall(b0.compare)');
22-
b0.compare(b1);
23-
24-
bench.start();
25-
for (var i = 0; i < iter; i++) {
26-
b0.compare(b1);
42+
switch (args) {
43+
case 2:
44+
b0.compare(b1, 0);
45+
bench.start();
46+
for (i = 0; i < iter; i++) {
47+
b0.compare(b1, 0);
48+
}
49+
bench.end(iter / 1e6);
50+
break;
51+
case 3:
52+
b0.compare(b1, 0, b1Len);
53+
bench.start();
54+
for (i = 0; i < iter; i++) {
55+
b0.compare(b1, 0, b1Len);
56+
}
57+
bench.end(iter / 1e6);
58+
break;
59+
case 4:
60+
b0.compare(b1, 0, b1Len, 0);
61+
bench.start();
62+
for (i = 0; i < iter; i++) {
63+
b0.compare(b1, 0, b1Len, 0);
64+
}
65+
bench.end(iter / 1e6);
66+
break;
67+
case 5:
68+
b0.compare(b1, 0, b1Len, 0, b0Len);
69+
bench.start();
70+
for (i = 0; i < iter; i++) {
71+
b0.compare(b1, 0, b1Len, 0, b0Len);
72+
}
73+
bench.end(iter / 1e6);
74+
break;
75+
default:
76+
b0.compare(b1);
77+
bench.start();
78+
for (i = 0; i < iter; i++) {
79+
b0.compare(b1);
80+
}
81+
bench.end(iter / 1e6);
2782
}
28-
bench.end(iter / 1e6);
2983
}

lib/buffer.js

+24-16
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
'use strict';
33

44
const binding = process.binding('buffer');
5+
const { compare: compare_, compareOffset } = binding;
56
const { isArrayBuffer, isSharedArrayBuffer } = process.binding('util');
67
const bindingObj = {};
78
const internalUtil = require('internal/util');
@@ -537,36 +538,43 @@ Buffer.prototype.compare = function compare(target,
537538

538539
if (!(target instanceof Buffer))
539540
throw new TypeError('Argument must be a Buffer');
541+
if (arguments.length === 1)
542+
return compare_(this, target);
540543

541544
if (start === undefined)
542545
start = 0;
546+
else if (start < 0)
547+
throw new RangeError('out of range index');
548+
else
549+
start >>>= 0;
550+
543551
if (end === undefined)
544552
end = target.length;
553+
else if (end > target.length)
554+
throw new RangeError('out of range index');
555+
else
556+
end >>>= 0;
557+
545558
if (thisStart === undefined)
546559
thisStart = 0;
560+
else if (thisStart < 0)
561+
throw new RangeError('out of range index');
562+
else
563+
thisStart >>>= 0;
564+
547565
if (thisEnd === undefined)
548566
thisEnd = this.length;
549-
550-
if (start < 0 ||
551-
end > target.length ||
552-
thisStart < 0 ||
553-
thisEnd > this.length) {
567+
else if (thisEnd > this.length)
554568
throw new RangeError('out of range index');
555-
}
569+
else
570+
thisEnd >>>= 0;
556571

557-
if (thisStart >= thisEnd && start >= end)
558-
return 0;
559572
if (thisStart >= thisEnd)
560-
return -1;
561-
if (start >= end)
573+
return (start >= end ? 0 : -1);
574+
else if (start >= end)
562575
return 1;
563576

564-
start >>>= 0;
565-
end >>>= 0;
566-
thisStart >>>= 0;
567-
thisEnd >>>= 0;
568-
569-
return binding.compareOffset(this, target, start, thisStart, end, thisEnd);
577+
return compareOffset(this, target, start, thisStart, end, thisEnd);
570578
};
571579

572580

0 commit comments

Comments
 (0)