Skip to content

Commit

Permalink
buffer: iterator optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
vkurchatkin committed Jan 20, 2015
1 parent 47a5310 commit 9aba596
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 12 deletions.
43 changes: 43 additions & 0 deletions benchmark/buffers/buffer-iterate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
var SlowBuffer = require('buffer').SlowBuffer;
var common = require('../common.js');
var assert = require('assert');

var bench = common.createBenchmark(main, {
size: [16, 512, 1024, 4096, 16386],
type: ['fast', 'slow'],
method: ['for', 'forOf'],
n: [1e3]
});

function main(conf) {
var len = +conf.size;
var clazz = conf.type === 'fast' ? Buffer : SlowBuffer;
var buffer = new clazz(len);
buffer.fill(0);

if (conf.method === 'for')
benchFor(buffer, conf.n);
else
benchForOf(buffer, conf.n);
}


function benchFor(buffer, n) {
bench.start();

for (var k = 0; k < n; k++)
for (var i = 0; i < buffer.length; i++)
assert(buffer[i] === 0);

bench.end(n);
}

function benchForOf(buffer, n) {
bench.start();

for (var k = 0; k < n; k++)
for (var b of buffer)
assert(b === 0);

bench.end(n);
}
45 changes: 34 additions & 11 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -934,43 +934,66 @@ Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
// ES6 iterator

var ITERATOR_KIND_KEYS = 1;
var ITERATOR_KIND_VALUES = 2;
var ITERATOR_KIND_ENTRIES = 3;

function BufferIteratorResult(value, done) {
this.value = value;
this.done = done;
}

var resultCache = new Array(256);

for (var i = 0; i < 256; i++)
resultCache[i] = Object.freeze(new BufferIteratorResult(i, false));

var finalResult = Object.freeze(new BufferIteratorResult(undefined, true));

function BufferIterator(buffer, kind) {
this._buffer = buffer;
this._kind = kind;
this._index = 0;
}

function BufferIteratorResult(value, done) {
this.value = value;
this.done = done;
}

BufferIterator.prototype.next = function() {
var buffer = this._buffer;
var kind = this._kind;
var index = this._index;

if (index >= buffer.length)
return new BufferIteratorResult(undefined, true);
return finalResult;

this._index++;

if (kind === ITERATOR_KIND_VALUES)
return new BufferIteratorResult(buffer[index], false);

if (kind === ITERATOR_KIND_ENTRIES)
return new BufferIteratorResult([index, buffer[index]], false);

return new BufferIteratorResult(index, false);
};

function BufferValueIterator(buffer) {
BufferIterator.call(this, buffer, null);
}

BufferValueIterator.prototype.next = function() {
var buffer = this._buffer;
var index = this._index;

if (index >= buffer.length)
return finalResult;

this._index++;

return resultCache[buffer[index]];
};


BufferIterator.prototype[Symbol.iterator] = function() {
return this;
};

BufferValueIterator.prototype[Symbol.iterator] =
BufferIterator.prototype[Symbol.iterator];

Buffer.prototype.keys = function() {
return new BufferIterator(this, ITERATOR_KIND_KEYS);
};
Expand All @@ -980,7 +1003,7 @@ Buffer.prototype.entries = function() {
};

Buffer.prototype.values = function() {
return new BufferIterator(this, ITERATOR_KIND_VALUES);
return new BufferValueIterator(this);
};

Buffer.prototype[Symbol.iterator] = Buffer.prototype.values;
2 changes: 1 addition & 1 deletion test/parallel/test-buffer-iterator.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var b;
arr = [];

for (b of buffer)
arr.push(b);
arr.push(b);

assert.deepEqual(arr, [1, 2, 3, 4, 5]);

Expand Down

0 comments on commit 9aba596

Please sign in to comment.