Skip to content

Commit ebeb6c0

Browse files
mscdexevanlucas
authored andcommitted
buffer: optimize write()
PR-URL: #12361 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 4d9e671 commit ebeb6c0

File tree

2 files changed

+120
-46
lines changed

2 files changed

+120
-46
lines changed
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const bench = common.createBenchmark(main, {
5+
encoding: [
6+
'', 'utf8', 'ascii', 'hex', 'UCS-2', 'utf16le', 'latin1', 'binary'
7+
],
8+
args: [ '', 'offset', 'offset+length' ],
9+
len: [10, 2048],
10+
n: [1e7]
11+
});
12+
13+
function main(conf) {
14+
const len = +conf.len;
15+
const n = +conf.n;
16+
const encoding = conf.encoding;
17+
const args = conf.args;
18+
19+
const string = 'a'.repeat(len);
20+
const buf = Buffer.allocUnsafe(len);
21+
22+
var i;
23+
24+
switch (args) {
25+
case 'offset':
26+
if (encoding) {
27+
bench.start();
28+
for (i = 0; i < n; ++i) {
29+
buf.write(string, 0, encoding);
30+
}
31+
bench.end(n);
32+
} else {
33+
bench.start();
34+
for (i = 0; i < n; ++i) {
35+
buf.write(string, 0);
36+
}
37+
bench.end(n);
38+
}
39+
break;
40+
case 'offset+length':
41+
if (encoding) {
42+
bench.start();
43+
for (i = 0; i < n; ++i) {
44+
buf.write(string, 0, buf.length, encoding);
45+
}
46+
bench.end(n);
47+
} else {
48+
bench.start();
49+
for (i = 0; i < n; ++i) {
50+
buf.write(string, 0, buf.length);
51+
}
52+
bench.end(n);
53+
}
54+
break;
55+
default:
56+
if (encoding) {
57+
bench.start();
58+
for (i = 0; i < n; ++i) {
59+
buf.write(string, encoding);
60+
}
61+
bench.end(n);
62+
} else {
63+
bench.start();
64+
for (i = 0; i < n; ++i) {
65+
buf.write(string);
66+
}
67+
bench.end(n);
68+
}
69+
}
70+
}

lib/buffer.js

+50-46
Original file line numberDiff line numberDiff line change
@@ -728,9 +728,7 @@ Buffer.prototype.fill = function fill(val, start, end, encoding) {
728728
Buffer.prototype.write = function(string, offset, length, encoding) {
729729
// Buffer#write(string);
730730
if (offset === undefined) {
731-
encoding = 'utf8';
732-
length = this.length;
733-
offset = 0;
731+
return this.utf8Write(string, 0, this.length);
734732

735733
// Buffer#write(string, encoding)
736734
} else if (length === undefined && typeof offset === 'string') {
@@ -743,12 +741,17 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
743741
offset = offset >>> 0;
744742
if (isFinite(length)) {
745743
length = length >>> 0;
746-
if (encoding === undefined)
747-
encoding = 'utf8';
748744
} else {
749745
encoding = length;
750746
length = undefined;
751747
}
748+
749+
var remaining = this.length - offset;
750+
if (length === undefined || length > remaining)
751+
length = remaining;
752+
753+
if (string.length > 0 && (length < 0 || offset < 0))
754+
throw new RangeError('Attempt to write outside buffer bounds');
752755
} else {
753756
// if someone is still calling the obsolete form of write(), tell them.
754757
// we don't want eg buf.write("foo", "utf8", 10) to silently turn into
@@ -757,50 +760,51 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
757760
'is no longer supported');
758761
}
759762

760-
var remaining = this.length - offset;
761-
if (length === undefined || length > remaining)
762-
length = remaining;
763-
764-
if (string.length > 0 && (length < 0 || offset < 0))
765-
throw new RangeError('Attempt to write outside buffer bounds');
766-
767-
if (!encoding)
768-
encoding = 'utf8';
769-
770-
var loweredCase = false;
771-
for (;;) {
772-
switch (encoding) {
773-
case 'hex':
774-
return this.hexWrite(string, offset, length);
775-
776-
case 'utf8':
777-
case 'utf-8':
778-
return this.utf8Write(string, offset, length);
779-
780-
case 'ascii':
781-
return this.asciiWrite(string, offset, length);
782-
783-
case 'latin1':
784-
case 'binary':
763+
if (!encoding) return this.utf8Write(string, offset, length);
764+
765+
encoding += '';
766+
switch (encoding.length) {
767+
case 4:
768+
if (encoding === 'utf8') return this.utf8Write(string, offset, length);
769+
if (encoding === 'ucs2') return this.ucs2Write(string, offset, length);
770+
encoding = encoding.toLowerCase();
771+
if (encoding === 'utf8') return this.utf8Write(string, offset, length);
772+
if (encoding === 'ucs2') return this.ucs2Write(string, offset, length);
773+
break;
774+
case 5:
775+
if (encoding === 'utf-8') return this.utf8Write(string, offset, length);
776+
if (encoding === 'ascii') return this.asciiWrite(string, offset, length);
777+
if (encoding === 'ucs-2') return this.ucs2Write(string, offset, length);
778+
encoding = encoding.toLowerCase();
779+
if (encoding === 'utf-8') return this.utf8Write(string, offset, length);
780+
if (encoding === 'ascii') return this.asciiWrite(string, offset, length);
781+
if (encoding === 'ucs-2') return this.ucs2Write(string, offset, length);
782+
break;
783+
case 7:
784+
if (encoding === 'utf16le' || encoding.toLowerCase() === 'utf16le')
785+
return this.ucs2Write(string, offset, length);
786+
break;
787+
case 8:
788+
if (encoding === 'utf-16le' || encoding.toLowerCase() === 'utf-16le')
789+
return this.ucs2Write(string, offset, length);
790+
break;
791+
case 6:
792+
if (encoding === 'latin1' || encoding === 'binary')
785793
return this.latin1Write(string, offset, length);
786-
787-
case 'base64':
788-
// Warning: maxLength not taken into account in base64Write
794+
if (encoding === 'base64')
789795
return this.base64Write(string, offset, length);
790-
791-
case 'ucs2':
792-
case 'ucs-2':
793-
case 'utf16le':
794-
case 'utf-16le':
795-
return this.ucs2Write(string, offset, length);
796-
797-
default:
798-
if (loweredCase)
799-
throw new TypeError('Unknown encoding: ' + encoding);
800-
encoding = ('' + encoding).toLowerCase();
801-
loweredCase = true;
802-
}
796+
encoding = encoding.toLowerCase();
797+
if (encoding === 'latin1' || encoding === 'binary')
798+
return this.latin1Write(string, offset, length);
799+
if (encoding === 'base64')
800+
return this.base64Write(string, offset, length);
801+
break;
802+
case 3:
803+
if (encoding === 'hex' || encoding.toLowerCase() === 'hex')
804+
return this.hexWrite(string, offset, length);
805+
break;
803806
}
807+
throw new TypeError('Unknown encoding: ' + encoding);
804808
};
805809

806810

0 commit comments

Comments
 (0)