Reputation: 179
I have a for-loop from 0 to 8,019,000,000 that is extremely slow.
var totalCalcs = 0;
for (var i = 0; i < 8019000000; i++)
totalCalcs++;
window.alert(totalCalcs);
in chrome this takes between 30-60secs.
I also already tried variations like:
var totalCalcs = 0;
for (var i = 8019000000; i--; )
totalCalcs++;
window.alert(totalCalcs);
Didn't do too much difference unfortunately.
Is there anything I can do to speed this up?
Upvotes: 4
Views: 8149
Reputation: 633
Your example is rather trivial, and any answer may not be suitable for whatever code you're actually putting inside of a loop with that many iterations.
If your work can be done in parallel, then we can divide the work between several web workers.
You can read a nice introduction to web workers, and learn how to use them, here:
http://www.html5rocks.com/en/tutorials/workers/basics/
Figuring out how to divide the work is a challenge that depends entirely on what that work is. Because your example is so small, it's easy to divide the work among inline web workers; here is a function to create a worker that will invoke a function asynchronously:
var makeWorker = function (fn, args, callback) {
var fnString = 'self.addEventListener("message", function (e) {self.postMessage((' + fn.toString() + ').apply(this, e.data))});',
blob = new Blob([fnString], { type: 'text/javascript' }),
url = URL.createObjectURL(blob),
worker = new Worker(url);
worker.postMessage(args);
worker.addEventListener('message', function (e) {
URL.revokeObjectURL(url);
callback(e.data);
});
return worker;
};
The work that we want done is adding numbers, so here is a function to do that:
var calculateSubTotal = function (count) {
var sum = 0;
for (var i = 0; i < count; ++i) {
sum++;
}
return sum;
};
And when a worker finishes, we want to add his sum to the total AND tell us the result when all workers are finished, so here is our callback:
var total = 0, count = 0, numWorkers = 1,
workerFinished = function (subTotal) {
total += subTotal;
count++;
if (count == numWorkers) {
console.log(total);
}
};
And finally we can create a worker:
makeWorker(calculateSubTotal, [10], workerFinished); // logs `10` to console
When put together, these pieces can calculate your large sum quickly (depending on how many CPUs your computer has, of course).
I have a complete example on jsfiddle.
Upvotes: 3
Reputation: 122906
Treating your question as a more generic question about speeding up loops with many iterations: you could try Duff's device.
In a test using nodejs the following code decreased the loop time from 108 seconds for your second loop (i--
) to 27 seconds
var testVal = 0, iterations = 8019000000;
var n = iterations % 8;
while (n--) {
testVal++;
}
n = parseInt(iterations / 8);
while (n--) {
testVal++;
testVal++;
testVal++;
testVal++;
testVal++;
testVal++;
testVal++;
testVal++;
}
Upvotes: 4