Skip to content

Commit

Permalink
buffer: optimize writing short strings
Browse files Browse the repository at this point in the history
PR-URL: #54310
  • Loading branch information
ronag committed Aug 11, 2024
1 parent 298ff4f commit 0261644
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 61 deletions.
20 changes: 20 additions & 0 deletions benchmark/buffers/buffer-write-string-short.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

const common = require('../common.js');
const bench = common.createBenchmark(main, {
len: [0, 1, 8, 16, 32],
fallback: [1, 0],
n: [1e6],
});

function main({ len, n, fallback }) {
const buf = Buffer.allocUnsafe(len);
const string = fallback && len > 0
? Buffer.from('a'.repeat(len - 1) + '€').toString()

Check failure on line 13 in benchmark/buffers/buffer-write-string-short.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

'?' should be placed at the end of the line
: Buffer.from('a'.repeat(len)).toString()

Check failure on line 14 in benchmark/buffers/buffer-write-string-short.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

':' should be placed at the end of the line

Check failure on line 14 in benchmark/buffers/buffer-write-string-short.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Missing semicolon
bench.start();
for (let i = 0; i < n; ++i) {
buf.write(string);
}
bench.end(n);
}
74 changes: 16 additions & 58 deletions benchmark/buffers/buffer-write-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,25 @@

const common = require('../common.js');
const bench = common.createBenchmark(main, {
encoding: [
'', 'utf8', 'ascii', 'hex', 'utf16le', 'latin1',
],
args: [ '', 'offset', 'offset+length' ],
len: [2048],
encoding: [ '', 'utf8', 'ascii' ],
len: [0, 1, 8, 16, 32],
n: [1e6],
});

function main({ len, n, encoding, args }) {
let string;
let start = 0;
function main({ len, n, encoding }) {
const buf = Buffer.allocUnsafe(len);

switch (args) {
case 'offset':
string = 'a'.repeat(Math.floor(len / 2));
start = len - string.length;
if (encoding) {
bench.start();
for (let i = 0; i < n; ++i) {
buf.write(string, start, encoding);
}
bench.end(n);
} else {
bench.start();
for (let i = 0; i < n; ++i) {
buf.write(string, start);
}
bench.end(n);
}
break;
case 'offset+length':
string = 'a'.repeat(len);
if (encoding) {
bench.start();
for (let i = 0; i < n; ++i) {
buf.write(string, 0, buf.length, encoding);
}
bench.end(n);
} else {
bench.start();
for (let i = 0; i < n; ++i) {
buf.write(string, 0, buf.length);
}
bench.end(n);
}
break;
default:
string = 'a'.repeat(len);
if (encoding) {
bench.start();
for (let i = 0; i < n; ++i) {
buf.write(string, encoding);
}
bench.end(n);
} else {
bench.start();
for (let i = 0; i < n; ++i) {
buf.write(string);
}
bench.end(n);
}
const string = 'a'.repeat(len);
if (encoding) {
bench.start();
for (let i = 0; i < n; ++i) {
buf.write(string, encoding);
}
bench.end(n);
} else {
bench.start();
for (let i = 0; i < n; ++i) {
buf.write(string);
}
bench.end(n);
}
}
27 changes: 24 additions & 3 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1082,10 +1082,10 @@ function _fill(buf, value, offset, end, encoding) {
Buffer.prototype.write = function write(string, offset, length, encoding) {
// Buffer#write(string);
if (offset === undefined) {
return this.utf8Write(string, 0, this.length);
}
offset = 0;
length = this.length;
// Buffer#write(string, encoding)
if (length === undefined && typeof offset === 'string') {
} else if (length === undefined && typeof offset === 'string') {
encoding = offset;
length = this.length;
offset = 0;
Expand All @@ -1108,6 +1108,27 @@ Buffer.prototype.write = function write(string, offset, length, encoding) {
}
}

const len = string?.length;
if (
len <= 16 &&
len <= length &&
(!encoding || encoding === 'ascii' || encoding === 'utf8') &&
typeof string === 'string'
) {
for (let n = 0; true; n++) {
if (n === len) {
return len;
}

const code = StringPrototypeCharCodeAt(string, n);
if (code >= 128) {
break;
}

this[offset + n] = code;
}
}

if (!encoding)
return this.utf8Write(string, offset, length);

Expand Down

0 comments on commit 0261644

Please sign in to comment.