Fastest Loop in JavaScript
In this post, I wanted to test whether choosing the right loop can actually make your app faster.
Since array access time is O(1), they’re already efficient but which loop handles them best?
Now you might say: “It doesn’t even matter. Machines are fast enough.” True in most cases. But not everyone has a high end device or blazing fast network.
The Experiment
Here are the loop types we’re comparing:
- for
- for of
- for in
- forEach
- while
Test case: Loop through 1,000,000 numbers and repeat that 1000 times for each loop type.
I ran the benchmark in two environments:
Each loop is measured with:
- Average time
- Median time
- Standard deviation
The Setup
Loop types are measured like this:
measureLoopType("for-of");
measureLoopType("for");
measureLoopType("for-in");
measureLoopType("forEach");
measureLoopType("while");
No external packages used. Just a simple getStats function that returns averages, medians, and std dev:
const getStats = (totalDurations) => {
const averageDuration =
totalDurations.reduce((acc, curr) => acc + curr, 0) / totalDurations.length;
const sortedDurations = [...totalDurations].sort((a, b) => a - b);
const mid = Math.floor(sortedDurations.length / 2);
const median =
sortedDurations.length % 2 !== 0
? sortedDurations[mid]
: (sortedDurations[mid - 1] + sortedDurations[mid]) / 2;
const mean = averageDuration;
const squareDiffs = totalDurations.map((value) => (value - mean) ** 2);
const avgSquareDiff =
squareDiffs.reduce((acc, curr) => acc + curr, 0) / squareDiffs.length;
const standardDeviation = Math.sqrt(avgSquareDiff);
return {
averageDuration,
median,
standardDeviation,
};
};
Next, define the number array and tracking map:
const numbers = Array.from({ length: 1_000_000 }, (_, index) => index + 1);
const runs = 1000;
const totalDurations = new Map();
Benchmark logic:
const measureLoopType = (type) => {
for (let i = 0; i < runs; i++) {
const startTime = performance.now();
// loop goes here...
const endTime = performance.now();
const duration = endTime - startTime;
if (totalDurations.has(type)) {
totalDurations.get(type).push(duration);
} else {
totalDurations.set(type, [duration]);
}
}
};
Loop switch statement:
switch (type) {
case "for-of":
for (const number of numbers) {
// Operation
}
break;
case "for":
for (let i = 0; i < numbers.length; i++) {
// Operation
}
break;
// ... other loops
}
And finally, print the results:
let results = [];
totalDurations.forEach((value, key) => {
const stats = getStats(value);
results.push({
LoopType: key,
Average: `${stats.averageDuration.toFixed(4)} ms`,
Median: `${stats.median.toFixed(4)} ms`,
StdDev: `${stats.standardDeviation.toFixed(4)} ms`,
});
});
console.table(results);
Results
Bun

Bun gave me a surprise: forEach was the fastest loop.
Its average execution time was just 0.6244 ms with a very low standard deviation, fast and consistent.
The for and while loops followed closely.
But for-in was much slower, as expected.
In Bun, forEach is the winner. Unexpected, but real.
Node.js

In Node.js, the results were more predictable:
whilewas the fastest with a median of0.3099 msforwas almost identicalforEachwas a bit slowerfor-inwas again the slowest
Also, while had a small std dev of 0.1874 ms, showing reliable performance across iterations.
GitHub: Fastest Loop in JS
The biggest surprise: in Bun, forEach was the fastest.
It shows how runtime environments can affect performance, even in simple constructs like loops.
duhan