I'm making a website where using PHP, AJAX and Javascript the user can help to calculate PI, this is purely for learning purposes and I'm know there are more efficient ways to calculate PI.
I need to pick a random location and then look if it's in a circle, there for I have created this code
var size = 500;
function calculate() {
var Xpos = Math.floor(Math.random() * size);
var Ypos = Math.floor(Math.random() * size);
var dist = Math.hypot(Ypos-Xpos, size / 2 - size / 2);
if (dist <= size / 2) postMessage(true);
else postMessage(false);
setTimeout("calculate()", 1);
}
calculate();
Which works great, altough it could be faster since there's a unneeded timeout in there (I think its uneeded anyway), so If I just remove it and replace it with only calculate();
to speed it up I get this error
Uncaught RangeError: Maximum call stack size exceeded
How do I solve this, I would like to keep the worker working for every (or until the user closes the page)
EDIT:
To be clear, the code I posted above works! but it stops working when I replace setTimeout("calculate()", 1);
with calculate();
The advantage of workers is that they allow you to move the heavy processing from the main thread. If you remove the setTimeout
from your code you will still be sending a lot of processing to the main thread, not anymore for calculating the PI, but still for processing the worker messages.
So, the idea is to process for as long as possible before sending a message to the main thread. For example, in your application you could run many iterations and send the result in one message:
const size = 500;
function calculate() {
const iterations = 100000;
while (true) { // you will probably want to have a condition to stop
let inside = 0;
for (let i = 0; i < iterations; i++) {
var Xpos = Math.floor(Math.random() * size);
var Ypos = Math.floor(Math.random() * size);
var dist = Math.hypot(Ypos-Xpos, size / 2 - size / 2);
if (dist <= size / 2) {
inside++;
}
}
postMessage({iterations, inside});
}
}
calculate();