PDA

View Full Version : Benchmarking Javascript



Fatt101
04-19-2014, 09:10 PM
Hi all,

First off i will display the JavaScript code I am working with;


function square() {
var before_loadtime = new Date().getTime();
var loops=1000;
for (i=0; i<loops; i++) {
squareit(); }
var aftr_loadtime = new Date().getTime();
pgloadtime = (aftr_loadtime - before_loadtime) / 1000;
document.getElementById("loadtime").innerHTML = "Page load time is <font color='red'><b>" + pgloadtime/loops + "</b></font> Seconds";
}
function squareit() {
var canvas = document.getElementById('canvas1');
if (canvas.getContext) {
var context = canvas.getContext('2d');

context.fillRect(25,25,100,100);
}
}

What I am struggling to understand is how to increase the accuracy of the program. I think I need to loop the JavaScript code for one second and then start the timer with the same amount of loops, which will then display the time it took to produce one iteration of the program more accurately?

I am not sure how I would go about doing this though, so any help/advice is very much appreciated.

Thanks,
Alex.

felgall
04-19-2014, 11:54 PM
The more loops you do the more accurate it will be - 1000 is too close to zero to give any meaningful result. Try 1000000 as a minimum.

Fatt101
04-20-2014, 12:07 AM
I don't think that matters since I am dividing the eventual number by itself to find out the time it took for it draw it once on the canvas, since the javascript timer only goes to 3 decimal places is why it is set to 1000 or else i wouldn't be able to get an accurate result?

Also, i think this explains what i am trying to do, but i am unsure how to, although it seems like it should be easy;

"One useful trick with setTimeout() is to register a function to be invoked after a delay of 0 milliseconds. The code isn't invoked right away but is run as soon as possible. In practice, setTimeout() tells the browser to invoke the function when it has finished running the event handlers for any currently pending events and has finished updating the current state of the document".

Fatt101
04-20-2014, 12:46 AM
function square() {
var before_loadtime = new Date().getTime();


var loops=1000;
for (i=0; i<loops; i++)
{setTimeout(function(){alert("Hello")},1000);
squareit(); }
var aftr_loadtime = new Date().getTime();
pgloadtime = (aftr_loadtime - before_loadtime) / 1000;
document.getElementById("loadtime").innerHTML = "Page load time is <font color='red'><b>" + pgloadtime/loops + "</b></font> Seconds";
}
// put into a loop
function squareit() {
var canvas = document.getElementById('canvas1');
if (canvas.getContext) {
var context = canvas.getContext('2d');

context.fillRect(25,25,100,100);
}
}

So i assume i put that bit of code in somewhere, or something similar to it to delay the function for a second before it runs the test?

felgall
04-20-2014, 01:04 AM
Timeouts run asynchronously - they do not delay the current execution as they will run after it.

Fatt101
04-20-2014, 02:13 AM
Is there a way to do what I want to do?

felgall
04-20-2014, 03:36 AM
Yes but you'd need to rewrite the code so it uses setTimeout instead of the loop.

rnd me
04-20-2014, 07:36 PM
in general, i use the following rough timer functionality:



var start=new Date();

// do a bunch of stuff, prefereably in a loop here
console.log("Operation took "+(new Date() - start )+" ms");



you can use performance.now() instead of new Date() for higher-resolution snapshots.



function square() {
var start=new Date();
var before_loadtime = new Date().getTime();
var loops=1000;
for (i=0; i<loops; i++) { squareit(); }
var aftr_loadtime = new Date().getTime();
pgloadtime = (aftr_loadtime - before_loadtime) / 1000;
console.log("Operation took "+(new Date() - start )+" ms");
document.getElementById("loadtime").innerHTML = "Page load time is <font color='red'><b>" + pgloadtime/loops + "</b></font> Seconds";
}
function squareit() {
var canvas = document.getElementById('canvas1');
if (canvas.getContext) {
var context = canvas.getContext('2d');

context.fillRect(25,25,100,100);
}
}

Fatt101
04-24-2014, 06:08 PM
Thanks for the help so far I've had a few days looking at things and since this is for a mobile application i don't think i will be able to use the performance.now()?

I want to try and code the benchmark to return the amount of iterations in a second, Ive found this code snippet online but i'm not sure how i can use it in this context?



var hz,
period,
startTime = new Date,
runs = 0;
do {
// Code snippet goes here
runs++;
totalTime = new Date - startTime;
} while (totalTime < 1000);

// convert ms to seconds
totalTime /= 1000;

// period → how long per operation
period = totalTime / runs;

// hz → the number of operations per second
hz = 1 / period;

// can be shortened to
// hz = (runs * 1000) / totalTime;