Skip to content

Commit e397e6f

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

File tree

2 files changed

+87
-25
lines changed

2 files changed

+87
-25
lines changed

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

Lines changed: 63 additions & 9 deletions
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

Lines changed: 24 additions & 16 deletions
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');
@@ -529,36 +530,43 @@ Buffer.prototype.compare = function compare(target,
529530

530531
if (!(target instanceof Buffer))
531532
throw new TypeError('Argument must be a Buffer');
533+
if (arguments.length === 1)
534+
return compare_(this, target);
532535

533536
if (start === undefined)
534537
start = 0;
538+
else if (start < 0)
539+
throw new RangeError('out of range index');
540+
else
541+
start >>>= 0;
542+
535543
if (end === undefined)
536544
end = target.length;
545+
else if (end > target.length)
546+
throw new RangeError('out of range index');
547+
else
548+
end >>>= 0;
549+
537550
if (thisStart === undefined)
538551
thisStart = 0;
552+
else if (thisStart < 0)
553+
throw new RangeError('out of range index');
554+
else
555+
thisStart >>>= 0;
556+
539557
if (thisEnd === undefined)
540558
thisEnd = this.length;
541-
542-
if (start < 0 ||
543-
end > target.length ||
544-
thisStart < 0 ||
545-
thisEnd > this.length) {
559+
else if (thisEnd > this.length)
546560
throw new RangeError('out of range index');
547-
}
561+
else
562+
thisEnd >>>= 0;
548563

549-
if (thisStart >= thisEnd && start >= end)
550-
return 0;
551564
if (thisStart >= thisEnd)
552-
return -1;
553-
if (start >= end)
565+
return (start >= end ? 0 : -1);
566+
else if (start >= end)
554567
return 1;
555568

556-
start >>>= 0;
557-
end >>>= 0;
558-
thisStart >>>= 0;
559-
thisEnd >>>= 0;
560-
561-
return binding.compareOffset(this, target, start, thisStart, end, thisEnd);
569+
return compareOffset(this, target, start, thisStart, end, thisEnd);
562570
};
563571

564572

0 commit comments

Comments
 (0)