NeTT
NeTT11mo ago

Speed of generators

How fast are JS generators when used as iterators? To be clear, I see the for..of loop being very slow compared to a plain for or while loop when used on arrays. Is it because the for..of loop is inherently slow or because the iterator behind it is slow?
10 Replies
NeTT
NeTT11mo ago
I'm using a generator for iterating through rows and columns in a "matrix". I'm afraid they'd be too slow for proper use.
marvinh.
marvinh.11mo ago
I'd just measure the differences in your particular use case given the data size you'll be expecting. My experience is that generators are a bit slower in microbenchmarks, but it really only starts to matter in the real world when the iteration count is high enough that it shows up in measurements
NeTT
NeTT11mo ago
Ay I'll try to do that
Hexagon
Hexagon11mo ago
Late answer, but an interesting topic <:cookie_deno:1002977285734932480> I agree with marvinh, you should profile your code to see if the actual loop are the bottleneck. If so, is it possible to reduce iteration count? Is it possible to offload these operations to a (rust or whatever) microservice, or offload to wasm within the application? What if you micro-optimize to reasonable performance, and the load/volume increase later? I've found myself having questions like these a couple of times. It has always resulted in a completely different solution at the end 🥸 If you're just curious, you should microbenhmark the sh*t out of it <:party_deno:1035517691517218847> , something like https://github.com/Hexagon/primer (but with loops)
GitHub
GitHub - Hexagon/primer: Benchmark of prime number calculation on p...
Benchmark of prime number calculation on pure javascript vs. wasm - GitHub - Hexagon/primer: Benchmark of prime number calculation on pure javascript vs. wasm
NeTT
NeTT11mo ago
Okay so I ran a benchmark on my matrix between the iterators and using a for loop with indexing. Matrix is stored as a single, long typed array so accessing rows is way faster than columns.
NeTT
NeTT11mo ago
For 100,000 rows and 1,000 columns
NeTT
NeTT11mo ago
And now I did one for 10,000,000 rows and 100 columns
NeTT
NeTT11mo ago
NeTT
NeTT11mo ago
The generators do not seem to reduce performance by a lot. Going with a 10k x 10x square matrix,
NeTT
NeTT11mo ago
import { Matrix } from "https://deno.land/x/vectorizer@v0.0.12/mod.ts";
const matrix = new Matrix(Uint8Array, [1e4, 1e4]);

Deno.bench({
name: "No Op",
fn() {
null;
},
});
Deno.bench({
name: "Generator (Row)",
fn() {
for (const row of matrix.rows()) {
row;
}
},
});
Deno.bench({
name: "Loop (Row)",
fn() {
for (let i = 0; i < matrix.nRows; i += 1) {
matrix.row(i);
}
},
});
Deno.bench({
name: "Generator (Col)",
fn() {
for (const col of matrix.cols()) {
col;
}
},
});
Deno.bench({
name: "Loop (Col)",
fn() {
for (let i = 0; i < matrix.nCols; i += 1) {
matrix.col(i);
}
},
});
import { Matrix } from "https://deno.land/x/vectorizer@v0.0.12/mod.ts";
const matrix = new Matrix(Uint8Array, [1e4, 1e4]);

Deno.bench({
name: "No Op",
fn() {
null;
},
});
Deno.bench({
name: "Generator (Row)",
fn() {
for (const row of matrix.rows()) {
row;
}
},
});
Deno.bench({
name: "Loop (Row)",
fn() {
for (let i = 0; i < matrix.nRows; i += 1) {
matrix.row(i);
}
},
});
Deno.bench({
name: "Generator (Col)",
fn() {
for (const col of matrix.cols()) {
col;
}
},
});
Deno.bench({
name: "Loop (Col)",
fn() {
for (let i = 0; i < matrix.nCols; i += 1) {
matrix.col(i);
}
},
});