Skip to content

Commit 31c64b3

Browse files
authored
Merge pull request #25 from benlesh/iteration-perf
Iteration perf improvements
2 parents ac908bf + 1a4cda9 commit 31c64b3

File tree

3 files changed

+127
-56
lines changed

3 files changed

+127
-56
lines changed

benchmark/issue25.js

Lines changed: 56 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,46 +14,72 @@ function ForEachBench() {
1414
console.log("starting forEach benchmark");
1515
const tb = new TypedFastBitSet();
1616
const stb = new SparseTypedFastBitSet();
17+
const tb_small = new TypedFastBitSet();
1718

1819
const s = new Set();
1920
for (let i = 0; i < N; i++) {
21+
if (i < 100) {
22+
tb_small.add(i);
23+
}
2024
tb.add(smallgap * i + 5);
2125
stb.add(smallgap * i + 5);
2226
}
2327

2428
const suite = new Benchmark.Suite();
2529
// add tests
2630
const ms = suite
27-
.add("TypedFastBitSet-forof", function () {
28-
let card = 0;
29-
for (const element of stb) {
30-
card++;
31-
}
32-
return card;
33-
})
34-
.add("TypedFastBitSet-foreach", function () {
35-
let card = 0;
36-
const inc = function () {
37-
card++;
38-
};
39-
tb.forEach(inc);
40-
return card;
41-
})
42-
.add("SparseTypedFastBitSet-forof", function () {
43-
let card = 0;
44-
for (const element of stb) {
45-
card++;
46-
}
47-
return card;
48-
})
49-
.add("SparseTypedFastBitSet-foreach", function () {
50-
let card = 0;
51-
const inc = function () {
52-
card++;
53-
};
54-
tb.forEach(inc);
55-
return card;
56-
})
31+
.add("TypedFastBitSet-forof", function () {
32+
let card = 0;
33+
for (const element of stb) {
34+
card++;
35+
}
36+
return card;
37+
})
38+
.add("TypedFastBitSet-foreach", function () {
39+
let card = 0;
40+
const inc = function () {
41+
card++;
42+
};
43+
tb.forEach(inc);
44+
return card;
45+
})
46+
.add("SparseTypedFastBitSet-forof", function () {
47+
let card = 0;
48+
for (const element of stb) {
49+
card++;
50+
}
51+
return card;
52+
})
53+
.add("SparseTypedFastBitSet-foreach", function () {
54+
let card = 0;
55+
const inc = function () {
56+
card++;
57+
};
58+
tb.forEach(inc);
59+
return card;
60+
})
61+
.add("TypedFastBitSet-nested-forof", function () {
62+
let card = 0;
63+
for (const x of tb_small) {
64+
for (const y of tb_small) {
65+
for (const z of tb_small) {
66+
card += x + y + z;
67+
}
68+
}
69+
}
70+
return card;
71+
})
72+
.add("TypedFastBitSet-nested-forEach", function () {
73+
let card = 0;
74+
tb_small.forEach(function (x) {
75+
tb_small.forEach(function (y) {
76+
tb_small.forEach(function (z) {
77+
card += x + y + z;
78+
});
79+
});
80+
});
81+
return card;
82+
})
5783
// add listeners
5884
.on("cycle", function (event) {
5985
console.log(String(event.target));
@@ -62,7 +88,6 @@ function ForEachBench() {
6288
.run({ async: false });
6389
}
6490

65-
6691
const main = function () {
6792
console.log(
6893
"Platform: " + process.platform + " " + os.release() + " " + process.arch

src/SparseTypedFastBitSet.ts

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -545,27 +545,57 @@ export class SparseTypedFastBitSet implements BitSet {
545545
/**
546546
* Iterator of set bit locations (values)
547547
*/
548-
*[Symbol.iterator](): IterableIterator<number> {
548+
[Symbol.iterator](): IterableIterator<number> {
549549
if (this.arraySize === -1) {
550550
const words = this.data;
551551
const c = words.length;
552-
for (let k = 0; k < c; ++k) {
553-
let w = words[k];
554-
while (w != 0) {
555-
const t = w & -w;
556-
yield (k << 5) + hammingWeight((t - 1) | 0);
557-
w ^= t;
558-
}
559-
}
552+
let k = 0;
553+
let w = words[k];
554+
555+
return {
556+
[Symbol.iterator]() {
557+
return this;
558+
},
559+
next() {
560+
while (k < c) {
561+
if (w !== 0) {
562+
const t = w & -w;
563+
const value = (k << 5) + hammingWeight((t - 1) | 0);
564+
w ^= t;
565+
return { done: false, value };
566+
} else {
567+
k++;
568+
if (k < c) {
569+
w = words[k];
570+
}
571+
}
572+
}
573+
return { done: true, value: undefined };
574+
},
575+
};
560576
} else {
561577
const array = this.data;
562-
for (let i = 0; i < this.arraySize; i++) {
563-
const v = array[i];
564-
yield v;
565-
if (v !== array[i]) {
566-
i--;
567-
}
568-
}
578+
const arraySize = this.arraySize;
579+
let i = 0;
580+
581+
return {
582+
[Symbol.iterator]() {
583+
return this;
584+
},
585+
next() {
586+
if (i < arraySize) {
587+
const v = array[i];
588+
const result = { done: false, value: v };
589+
if (v !== array[i]) {
590+
i--;
591+
}
592+
i++;
593+
return result;
594+
} else {
595+
return { done: true, value: undefined };
596+
}
597+
},
598+
};
569599
}
570600
}
571601

src/TypedFastBitSet.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -265,17 +265,33 @@ export class TypedFastBitSet implements BitSet {
265265
/**
266266
* Iterator of set bit locations (values)
267267
*/
268-
*[Symbol.iterator](): IterableIterator<number> {
268+
[Symbol.iterator](): IterableIterator<number> {
269269
const words = this.words;
270270
const c = words.length;
271-
for (let k = 0; k < c; ++k) {
272-
let w = words[k];
273-
while (w != 0) {
274-
const t = w & -w;
275-
yield (k << 5) + hammingWeight((t - 1) | 0);
276-
w ^= t;
277-
}
278-
}
271+
let k = 0;
272+
let w = words[k];
273+
274+
return {
275+
[Symbol.iterator]() {
276+
return this;
277+
},
278+
next() {
279+
while (k < c) {
280+
if (w !== 0) {
281+
const t = w & -w;
282+
const value = (k << 5) + hammingWeight((t - 1) | 0);
283+
w ^= t;
284+
return { done: false, value };
285+
} else {
286+
k++;
287+
if (k < c) {
288+
w = words[k];
289+
}
290+
}
291+
}
292+
return { done: true, value: undefined };
293+
},
294+
};
279295
}
280296

281297
/**

0 commit comments

Comments
 (0)