Skip to content

Commit d67e2f7

Browse files
committed
buffer: iterator optimization
1 parent 47a5310 commit d67e2f7

File tree

3 files changed

+78
-33
lines changed

3 files changed

+78
-33
lines changed

benchmark/buffers/buffer-iterate.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
var SlowBuffer = require('buffer').SlowBuffer;
2+
var common = require('../common.js');
3+
var assert = require('assert');
4+
5+
var bench = common.createBenchmark(main, {
6+
size: [16, 512, 1024, 4096, 16386],
7+
type: ['fast', 'slow'],
8+
method: ['for', 'forOf'],
9+
n: [1e3]
10+
});
11+
12+
function main(conf) {
13+
var len = +conf.size;
14+
var clazz = conf.type === 'fast' ? Buffer : SlowBuffer;
15+
var buffer = new clazz(len);
16+
buffer.fill(0);
17+
18+
if (conf.method === 'for')
19+
benchFor(buffer, conf.n);
20+
else
21+
benchForOf(buffer, conf.n);
22+
}
23+
24+
25+
function benchFor(buffer, n) {
26+
bench.start();
27+
28+
for (var k = 0; k < n; k++)
29+
for (var i = 0; i < buffer.length; i++)
30+
assert(buffer[i] === 0);
31+
32+
bench.end(n);
33+
}
34+
35+
function benchForOf(buffer, n) {
36+
bench.start();
37+
38+
for (var k = 0; k < n; k++)
39+
for (var b of buffer)
40+
assert(b === 0);
41+
42+
bench.end(n);
43+
}

lib/buffer.js

+34-11
Original file line numberDiff line numberDiff line change
@@ -934,43 +934,66 @@ Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
934934
// ES6 iterator
935935

936936
var ITERATOR_KIND_KEYS = 1;
937-
var ITERATOR_KIND_VALUES = 2;
938937
var ITERATOR_KIND_ENTRIES = 3;
939938

939+
function BufferIteratorResult(value, done) {
940+
this.value = value;
941+
this.done = done;
942+
}
943+
944+
var resultCache = new Array(256);
945+
946+
for (var i = 0; i < 256; i++)
947+
resultCache[i] = Object.freeze(new BufferIteratorResult(i, false));
948+
949+
var finalResult = Object.freeze(new BufferIteratorResult(undefined, true));
950+
940951
function BufferIterator(buffer, kind) {
941952
this._buffer = buffer;
942953
this._kind = kind;
943954
this._index = 0;
944955
}
945956

946-
function BufferIteratorResult(value, done) {
947-
this.value = value;
948-
this.done = done;
949-
}
950-
951957
BufferIterator.prototype.next = function() {
952958
var buffer = this._buffer;
953959
var kind = this._kind;
954960
var index = this._index;
955961

956962
if (index >= buffer.length)
957-
return new BufferIteratorResult(undefined, true);
963+
return finalResult;
958964

959965
this._index++;
960966

961-
if (kind === ITERATOR_KIND_VALUES)
962-
return new BufferIteratorResult(buffer[index], false);
963-
964967
if (kind === ITERATOR_KIND_ENTRIES)
965968
return new BufferIteratorResult([index, buffer[index]], false);
966969

967970
return new BufferIteratorResult(index, false);
968971
};
969972

973+
function BufferValueIterator(buffer) {
974+
BufferIterator.call(this, buffer, null);
975+
}
976+
977+
BufferValueIterator.prototype.next = function() {
978+
var buffer = this._buffer;
979+
var index = this._index;
980+
981+
if (index >= buffer.length)
982+
return finalResult;
983+
984+
this._index++;
985+
986+
return resultCache[buffer[index]];
987+
};
988+
989+
970990
BufferIterator.prototype[Symbol.iterator] = function() {
971991
return this;
972992
};
973993

994+
BufferValueIterator.prototype[Symbol.iterator] =
995+
BufferIterator.prototype[Symbol.iterator];
996+
974997
Buffer.prototype.keys = function() {
975998
return new BufferIterator(this, ITERATOR_KIND_KEYS);
976999
};
@@ -980,7 +1003,7 @@ Buffer.prototype.entries = function() {
9801003
};
9811004

9821005
Buffer.prototype.values = function() {
983-
return new BufferIterator(this, ITERATOR_KIND_VALUES);
1006+
return new BufferValueIterator(this);
9841007
};
9851008

9861009
Buffer.prototype[Symbol.iterator] = Buffer.prototype.values;

test/parallel/test-buffer-iterator.js

+1-22
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,3 @@
1-
// Copyright io.js contributors.
2-
//
3-
// Permission is hereby granted, free of charge, to any person obtaining a
4-
// copy of this software and associated documentation files (the
5-
// "Software"), to deal in the Software without restriction, including
6-
// without limitation the rights to use, copy, modify, merge, publish,
7-
// distribute, sublicense, and/or sell copies of the Software, and to permit
8-
// persons to whom the Software is furnished to do so, subject to the
9-
// following conditions:
10-
//
11-
// The above copyright notice and this permission notice shall be included
12-
// in all copies or substantial portions of the Software.
13-
//
14-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15-
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16-
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17-
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18-
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19-
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20-
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21-
221
var common = require('../common');
232
var assert = require('assert');
243

@@ -31,7 +10,7 @@ var b;
3110
arr = [];
3211

3312
for (b of buffer)
34-
arr.push(b);
13+
arr.push(b);
3514

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

0 commit comments

Comments
 (0)