Browse Source

buffer: optimize write()

PR-URL: https://github.com/nodejs/node/pull/12361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
v7.x
Brian White 8 years ago
committed by Evan Lucas
parent
commit
ebeb6c0a26
  1. 70
      benchmark/buffers/buffer-write-string.js
  2. 96
      lib/buffer.js

70
benchmark/buffers/buffer-write-string.js

@ -0,0 +1,70 @@
'use strict';
const common = require('../common.js');
const bench = common.createBenchmark(main, {
encoding: [
'', 'utf8', 'ascii', 'hex', 'UCS-2', 'utf16le', 'latin1', 'binary'
],
args: [ '', 'offset', 'offset+length' ],
len: [10, 2048],
n: [1e7]
});
function main(conf) {
const len = +conf.len;
const n = +conf.n;
const encoding = conf.encoding;
const args = conf.args;
const string = 'a'.repeat(len);
const buf = Buffer.allocUnsafe(len);
var i;
switch (args) {
case 'offset':
if (encoding) {
bench.start();
for (i = 0; i < n; ++i) {
buf.write(string, 0, encoding);
}
bench.end(n);
} else {
bench.start();
for (i = 0; i < n; ++i) {
buf.write(string, 0);
}
bench.end(n);
}
break;
case 'offset+length':
if (encoding) {
bench.start();
for (i = 0; i < n; ++i) {
buf.write(string, 0, buf.length, encoding);
}
bench.end(n);
} else {
bench.start();
for (i = 0; i < n; ++i) {
buf.write(string, 0, buf.length);
}
bench.end(n);
}
break;
default:
if (encoding) {
bench.start();
for (i = 0; i < n; ++i) {
buf.write(string, encoding);
}
bench.end(n);
} else {
bench.start();
for (i = 0; i < n; ++i) {
buf.write(string);
}
bench.end(n);
}
}
}

96
lib/buffer.js

@ -728,9 +728,7 @@ Buffer.prototype.fill = function fill(val, start, end, encoding) {
Buffer.prototype.write = function(string, offset, length, encoding) {
// Buffer#write(string);
if (offset === undefined) {
encoding = 'utf8';
length = this.length;
offset = 0;
return this.utf8Write(string, 0, this.length);
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
@ -743,19 +741,10 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
offset = offset >>> 0;
if (isFinite(length)) {
length = length >>> 0;
if (encoding === undefined)
encoding = 'utf8';
} else {
encoding = length;
length = undefined;
}
} else {
// if someone is still calling the obsolete form of write(), tell them.
// we don't want eg buf.write("foo", "utf8", 10) to silently turn into
// buf.write("foo", "utf8"), so we can't ignore extra args
throw new Error('Buffer.write(string, encoding, offset[, length]) ' +
'is no longer supported');
}
var remaining = this.length - offset;
if (length === undefined || length > remaining)
@ -763,44 +752,59 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
if (string.length > 0 && (length < 0 || offset < 0))
throw new RangeError('Attempt to write outside buffer bounds');
} else {
// if someone is still calling the obsolete form of write(), tell them.
// we don't want eg buf.write("foo", "utf8", 10) to silently turn into
// buf.write("foo", "utf8"), so we can't ignore extra args
throw new Error('Buffer.write(string, encoding, offset[, length]) ' +
'is no longer supported');
}
if (!encoding)
encoding = 'utf8';
var loweredCase = false;
for (;;) {
switch (encoding) {
case 'hex':
return this.hexWrite(string, offset, length);
case 'utf8':
case 'utf-8':
return this.utf8Write(string, offset, length);
case 'ascii':
return this.asciiWrite(string, offset, length);
case 'latin1':
case 'binary':
if (!encoding) return this.utf8Write(string, offset, length);
encoding += '';
switch (encoding.length) {
case 4:
if (encoding === 'utf8') return this.utf8Write(string, offset, length);
if (encoding === 'ucs2') return this.ucs2Write(string, offset, length);
encoding = encoding.toLowerCase();
if (encoding === 'utf8') return this.utf8Write(string, offset, length);
if (encoding === 'ucs2') return this.ucs2Write(string, offset, length);
break;
case 5:
if (encoding === 'utf-8') return this.utf8Write(string, offset, length);
if (encoding === 'ascii') return this.asciiWrite(string, offset, length);
if (encoding === 'ucs-2') return this.ucs2Write(string, offset, length);
encoding = encoding.toLowerCase();
if (encoding === 'utf-8') return this.utf8Write(string, offset, length);
if (encoding === 'ascii') return this.asciiWrite(string, offset, length);
if (encoding === 'ucs-2') return this.ucs2Write(string, offset, length);
break;
case 7:
if (encoding === 'utf16le' || encoding.toLowerCase() === 'utf16le')
return this.ucs2Write(string, offset, length);
break;
case 8:
if (encoding === 'utf-16le' || encoding.toLowerCase() === 'utf-16le')
return this.ucs2Write(string, offset, length);
break;
case 6:
if (encoding === 'latin1' || encoding === 'binary')
return this.latin1Write(string, offset, length);
case 'base64':
// Warning: maxLength not taken into account in base64Write
if (encoding === 'base64')
return this.base64Write(string, offset, length);
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return this.ucs2Write(string, offset, length);
default:
if (loweredCase)
throw new TypeError('Unknown encoding: ' + encoding);
encoding = ('' + encoding).toLowerCase();
loweredCase = true;
}
encoding = encoding.toLowerCase();
if (encoding === 'latin1' || encoding === 'binary')
return this.latin1Write(string, offset, length);
if (encoding === 'base64')
return this.base64Write(string, offset, length);
break;
case 3:
if (encoding === 'hex' || encoding.toLowerCase() === 'hex')
return this.hexWrite(string, offset, length);
break;
}
throw new TypeError('Unknown encoding: ' + encoding);
};

Loading…
Cancel
Save