Skip to content

Instantly share code, notes, and snippets.

@easrng
Created May 29, 2025 02:55
Show Gist options
  • Save easrng/5ab2f2d49309d40462054a4beca1de5c to your computer and use it in GitHub Desktop.
Save easrng/5ab2f2d49309d40462054a4beca1de5c to your computer and use it in GitHub Desktop.
/*
$ deno bench iter.js
CPU | 13th Gen Intel(R) Core(TM) i7-1365U
Runtime | Deno 2.2.8 (x86_64-unknown-linux-gnu)
file:///tmp/iter.js
benchmark time/iter (avg) iter/s (min … max) p75 p99 p995
------------------- ----------------------------- --------------------- --------------------------
for 4.4 µs 225,600 ( 4.4 µs … 4.5 µs) 4.4 µs 4.5 µs 4.5 µs
default iterator 6.7 µs 149,700 ( 6.6 µs … 27.0 µs) 6.7 µs 6.8 µs 8.3 µs
SafeArrayIterator 53.3 µs 18,750 ( 48.2 µs … 186.0 µs) 49.9 µs 91.6 µs 93.5 µs
CustomIterator1 36.6 µs 27,300 ( 25.3 µs … 676.6 µs) 33.4 µs 72.9 µs 75.1 µs
CustomIterator2 587.6 µs 1,702 (531.5 µs … 700.9 µs) 614.8 µs 648.5 µs 657.3 µs
CustomIterator3 36.7 µs 27,250 ( 25.1 µs … 250.6 µs) 33.5 µs 73.2 µs 75.9 µs
CustomIterator4 34.1 µs 29,300 ( 27.9 µs … 172.1 µs) 31.0 µs 71.5 µs 73.7 µs
CustomIterator5 30.9 µs 32,310 ( 24.7 µs … 212.9 µs) 27.7 µs 68.3 µs 70.8 µs
CustomIterator6 13.5 µs 74,240 ( 13.2 µs … 161.2 µs) 13.6 µs 15.2 µs 15.7 µs
CustomIterator7 16.0 µs 62,520 ( 15.9 µs … 145.6 µs) 15.9 µs 17.7 µs 18.3 µs
CustomGenerator 12.5 µs 80,220 ( 11.9 µs … 179.4 µs) 12.4 µs 22.4 µs 22.4 µs
generator 98.7 µs 10,130 ( 85.8 µs … 220.5 µs) 103.3 µs 139.1 µs 141.1 µs
for (no array) 3.5 µs 283,100 ( 3.5 µs … 3.5 µs) 3.5 µs 3.5 µs 3.5 µs
*/
import assert from "node:assert";
const SafeArrayIterator = (() => {
var { bind, call } = Function.prototype;
var uncurryThis = bind.bind(call);
var SymbolIterator = Symbol.iterator;
var ReflectGetPrototypeOf = Reflect.getPrototypeOf;
var ArrayPrototype = Array.prototype;
var ArrayPrototypeSymbolIterator = uncurryThis(
ArrayPrototype[SymbolIterator],
);
var ObjectSetPrototypeOf = Object.setPrototypeOf;
var ObjectFreeze = Object.freeze;
var createSafeIterator = (factory, next) => {
class SafeIterator {
#iterator;
constructor(iterable) {
this.#iterator = factory(iterable);
}
next() {
return next(this.#iterator);
}
[SymbolIterator]() {
return this;
}
}
ObjectSetPrototypeOf(SafeIterator.prototype, null);
ObjectFreeze(SafeIterator.prototype);
ObjectFreeze(SafeIterator);
return SafeIterator;
};
var ArrayIteratorPrototype = ReflectGetPrototypeOf(
ArrayPrototype[SymbolIterator](),
);
var ArrayIteratorPrototypeNext = uncurryThis(ArrayIteratorPrototype.next);
var SafeArrayIterator = createSafeIterator(
ArrayPrototypeSymbolIterator,
ArrayIteratorPrototypeNext,
);
return SafeArrayIterator;
})();
class CustomIterator1 {
constructor(array) {
this.index = 0;
this.array = array;
}
next() {
if (this.index >= this.array.length) {
return { done: true, value: undefined };
}
return { done: false, value: this.array[this.index++] };
}
[Symbol.iterator]() {
return this;
}
}
class CustomIterator2 {
constructor(array) {
this.index = 0;
this.array = array;
}
next() {
if (this.index >= this.array.length) {
return { __proto__: null, done: true, value: undefined };
}
return { __proto__: null, done: false, value: this.array[this.index++] };
}
[Symbol.iterator]() {
return this;
}
}
Object.setPrototypeOf(CustomIterator2.prototype, null);
class CustomIterator3 {
constructor(array) {
this.index = 0;
this.array = array;
}
next() {
if (this.index >= this.array.length) {
return { done: true, value: undefined };
}
return { done: false, value: this.array[this.index++] };
}
[Symbol.iterator]() {
return this;
}
}
Object.setPrototypeOf(CustomIterator3.prototype, null);
class CustomIterator4Result {
constructor(done, value) {
this.done = done;
this.value = value;
}
}
Object.setPrototypeOf(CustomIterator4Result.prototype, null);
class CustomIterator4 {
constructor(array) {
this.index = 0;
this.array = array;
}
next() {
if (this.index >= this.array.length) {
return new CustomIterator4Result(true, undefined);
}
return new CustomIterator4Result(false, this.array[this.index++]);
}
[Symbol.iterator]() {
return this;
}
}
Object.setPrototypeOf(CustomIterator4.prototype, null);
class CustomIterator5 {
#index;
#array;
constructor(array) {
this.#index = 0;
this.#array = array;
}
next() {
if (this.#index >= this.#array.length) {
return new CustomIterator4Result(true, undefined);
}
return new CustomIterator4Result(false, this.#array[this.#index++]);
}
[Symbol.iterator]() {
return this;
}
}
Object.setPrototypeOf(CustomIterator5.prototype, null);
class CustomIterator6 {
constructor(array) {
this.index = 0;
this.array = array;
this.result = new CustomIterator4Result(false, undefined);
}
next() {
if (this.index >= this.array.length) {
this.result.done = true;
this.result.value = undefined;
} else {
this.result.done = false;
this.result.value = this.array[this.index++];
}
return this.result;
}
[Symbol.iterator]() {
return this;
}
}
Object.setPrototypeOf(CustomIterator6.prototype, null);
class CustomIterator7 {
constructor(array) {
this.index = 0;
this.array = array;
this.done = false;
this.value = undefined;
}
next() {
if (this.index >= this.array.length) {
this.done = true;
this.value = undefined;
} else {
this.done = false;
this.value = this.array[this.index++];
}
return this;
}
[Symbol.iterator]() {
return this;
}
}
Object.setPrototypeOf(CustomIterator7.prototype, null);
class CustomGenerator {
constructor(length) {
this.index = 0;
this.length = length;
this.result = new CustomIterator4Result(false, undefined);
}
next() {
if (this.index >= this.length) {
this.result.done = true;
this.result.value = undefined;
} else {
this.result.done = false;
this.result.value = this.index++;
}
return this.result;
}
[Symbol.iterator]() {
return this;
}
}
Object.setPrototypeOf(CustomGenerator.prototype, null);
var data = Array.from({ length: 10000 }, (_, i) => i);
Deno.bench("for", function fn() {
let sum = 0;
for (let i = 0; i < data.length; i++) sum += data[i];
assert.strictEqual(sum, 49995000);
});
Deno.bench("default iterator", function fn() {
let sum = 0;
for (let num of data) sum += num;
assert.strictEqual(sum, 49995000);
});
Deno.bench("SafeArrayIterator", function fn() {
let sum = 0;
for (let num of new SafeArrayIterator(data)) sum += num;
assert.strictEqual(sum, 49995000);
});
Deno.bench("CustomIterator1", function fn() {
let sum = 0;
for (let num of new CustomIterator1(data)) sum += num;
assert.strictEqual(sum, 49995000);
});
Deno.bench("CustomIterator2", function fn() {
let sum = 0;
for (let num of new CustomIterator2(data)) sum += num;
assert.strictEqual(sum, 49995000);
});
Deno.bench("CustomIterator3", function fn() {
let sum = 0;
for (let num of new CustomIterator3(data)) sum += num;
assert.strictEqual(sum, 49995000);
});
Deno.bench("CustomIterator4", function fn() {
let sum = 0;
for (let num of new CustomIterator4(data)) sum += num;
assert.strictEqual(sum, 49995000);
});
Deno.bench("CustomIterator5", function fn() {
let sum = 0;
for (let num of new CustomIterator5(data)) sum += num;
assert.strictEqual(sum, 49995000);
});
Deno.bench("CustomIterator6", function fn() {
let sum = 0;
for (let num of new CustomIterator6(data)) sum += num;
assert.strictEqual(sum, 49995000);
});
Deno.bench("CustomIterator7", function fn() {
let sum = 0;
for (let num of new CustomIterator7(data)) sum += num;
assert.strictEqual(sum, 49995000);
});
Deno.bench("CustomGenerator", function fn() {
let sum = 0;
for (let num of new CustomGenerator(10000)) sum += num;
assert.strictEqual(sum, 49995000);
});
function* gen() {
for (let i = 0; i < 10000; i++) yield i;
}
Deno.bench("generator", function fn() {
let sum = 0;
for (let num of gen()) sum += num;
assert.strictEqual(sum, 49995000);
});
Deno.bench("for (no array)", function fn() {
let sum = 0;
for (let i = 0; i < 10000; i++) sum += i;
assert.strictEqual(sum, 49995000);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment