Skip to content

Commit 8350f3a

Browse files
committed
buffer: optimize Buffer#toString()
Break up Buffer#toString() into a fast and slow path. The fast path optimizes for zero-length buffers and no-arg method invocation. The speedup for zero-length buffers is a satisfying 700%. The no-arg toString() operation gets faster by about 13% for a one-byte buffer. This change exploits the fact that most Buffer#toString() calls are plain no-arg method calls. Rewriting the method to take no arguments means a call doesn't go through an ArgumentsAdaptorTrampoline stack frame in the common case. PR-URL: #2027 Reviewed-By: Brian White <[email protected]> Reviewed-By: Christian Tellnes <[email protected]> Reviewed-By: Daniel Cousens <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Trevor Norris <[email protected]>
1 parent 06721fe commit 8350f3a

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

benchmark/buffers/buffer-tostring.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
5+
const bench = common.createBenchmark(main, {
6+
arg: [true, false],
7+
len: [0, 1, 64, 1024],
8+
n: [1e7]
9+
});
10+
11+
function main(conf) {
12+
const arg = conf.arg;
13+
const len = conf.len | 0;
14+
const n = conf.n | 0;
15+
const buf = Buffer(len).fill(42);
16+
17+
bench.start();
18+
if (arg) {
19+
for (var i = 0; i < n; i += 1)
20+
buf.toString('utf8');
21+
} else {
22+
for (var i = 0; i < n; i += 1)
23+
buf.toString();
24+
}
25+
bench.end(n);
26+
}

lib/buffer.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,7 @@ function byteLength(string, encoding) {
333333

334334
Buffer.byteLength = byteLength;
335335

336-
// toString(encoding, start=0, end=buffer.length)
337-
Buffer.prototype.toString = function(encoding, start, end) {
336+
function slowToString(encoding, start, end) {
338337
var loweredCase = false;
339338

340339
start = start >>> 0;
@@ -376,6 +375,16 @@ Buffer.prototype.toString = function(encoding, start, end) {
376375
loweredCase = true;
377376
}
378377
}
378+
}
379+
380+
381+
Buffer.prototype.toString = function() {
382+
const length = this.length | 0;
383+
if (length === 0)
384+
return '';
385+
if (arguments.length === 0)
386+
return this.utf8Slice(0, length);
387+
return slowToString.apply(this, arguments);
379388
};
380389

381390

0 commit comments

Comments
 (0)