Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
buffer: directly use ArrayBuffer as the pool
Make the buffer pool an `ArrayBuffer` which is used directly,
speeding up allocation noticeably in some cases.
The only drawback happens when creating pool-based `Buffer`
instances from strings whose byte lengths got overestimated
by `Buffer.byteLength`, e.g. for base64-encoded strings
containing whitespace, where two `Buffer` instances are
being created.

This may also be useful when providing Buffer classes in
the future.

Benchmark results for `benchmark/buffers/buffer-creation.js`:

```
                                 improvement significant      p.value
len=1024 type="buffer()"             47.11 %         *** 5.202555e-12
len=1024 type="fast-alloc"           -3.41 %             3.823226e-01
len=1024 type="fast-alloc-fill"       1.11 %             7.985624e-01
len=1024 type="fast-allocUnsafe"     24.37 %         *** 4.264084e-05
len=1024 type="slow"                  4.81 %             2.634609e-01
len=1024 type="slow-allocUnsafe"      1.28 %             7.864850e-01
len=10 type="buffer()"               59.42 %         *** 9.953552e-13
len=10 type="fast-alloc"             -6.43 %             1.450524e-01
len=10 type="fast-alloc-fill"        -2.96 %             4.873766e-01
len=10 type="fast-allocUnsafe"       33.89 %         *** 6.517268e-07
len=10 type="slow"                   -1.48 %             7.357711e-01
len=10 type="slow-allocUnsafe"        0.04 %             9.939576e-01
len=2048 type="buffer()"             36.34 %         *** 3.201045e-10
len=2048 type="fast-alloc"           -4.67 %             2.172900e-01
len=2048 type="fast-alloc-fill"      -0.15 %             9.732945e-01
len=2048 type="fast-allocUnsafe"     20.13 %         *** 2.372115e-04
len=2048 type="slow"                  4.35 %             2.831340e-01
len=2048 type="slow-allocUnsafe"      1.13 %             8.055388e-01
len=4096 type="buffer()"              4.90 %             2.495340e-01
len=4096 type="fast-alloc"           -2.11 %             5.417520e-01
len=4096 type="fast-alloc-fill"      -0.29 %             9.460378e-01
len=4096 type="fast-allocUnsafe"      3.11 %             5.001959e-01
len=4096 type="slow"                  0.95 %             8.145888e-01
len=4096 type="slow-allocUnsafe"      3.74 %             4.227627e-01
len=8192 type="buffer()"              5.08 %             2.263029e-01
len=8192 type="fast-alloc"           -1.16 %             7.300235e-01
len=8192 type="fast-alloc-fill"       0.40 %             9.179919e-01
len=8192 type="fast-allocUnsafe"      5.16 %             2.591544e-01
len=8192 type="slow"                  2.57 %             5.212449e-01
len=8192 type="slow-allocUnsafe"     -3.19 %             4.699138e-01
```
  • Loading branch information
addaleax committed Aug 27, 2016
commit 9e19ef8c88b810c56d3fda3b23fe0d79e84ae4b7
18 changes: 13 additions & 5 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,21 @@ binding.setupBufferJS(Buffer.prototype, bindingObj);
const zeroFill = bindingObj.zeroFill || [0];

function createUnsafeBuffer(size) {
return new FastBuffer(createUnsafeArrayBuffer(size));
}

function createUnsafeArrayBuffer(size) {
zeroFill[0] = 0;
try {
return new FastBuffer(size);
return new ArrayBuffer(size);
} finally {
zeroFill[0] = 1;
}
}

function createPool() {
poolSize = Buffer.poolSize;
allocPool = createUnsafeBuffer(poolSize);
allocPool = createUnsafeArrayBuffer(poolSize);
poolOffset = 0;
}
createPool();
Expand Down Expand Up @@ -183,7 +187,7 @@ function allocate(size) {
if (size < (Buffer.poolSize >>> 1)) {
if (size > (poolSize - poolOffset))
createPool();
var b = allocPool.slice(poolOffset, poolOffset + size);
var b = new FastBuffer(allocPool, poolOffset, size);
poolOffset += size;
alignPool();
return b;
Expand All @@ -210,8 +214,12 @@ function fromString(string, encoding) {

if (length > (poolSize - poolOffset))
createPool();
var actual = allocPool.write(string, poolOffset, encoding);
var b = allocPool.slice(poolOffset, poolOffset + actual);
var b = new FastBuffer(allocPool, poolOffset, length);
var actual = b.write(string, encoding);
if (actual !== length) {
// byteLength() may overestimate. That’s a rare case, though.
b = new FastBuffer(allocPool, poolOffset, actual);
}
poolOffset += actual;
alignPool();
return b;
Expand Down