14,974,357 members
Articles / Web Development
Article
Posted 24 Oct 2013

8.3K views
1 bookmarked

# The Odd Results From Trying to Performance Test... Circles

Rate me:
This little bit of code is an attempt to illustrate the performance difference between using a constant vs. always using 2*Math.PI when using the .arc() method to draw a circle to a canvas.

## Introduction

Drawing (a lot) of circles (or anything for that matter) on a particular HTML5 canvas can really bog down performance. This little bit of code is an attempt to illustrate the performance difference between using a constant vs. always using 2*`Math.PI` when using the `.arc()` method to draw a circle to a canvas.

## Background

I have a project that involves drawing an insane amount of circles to an HTML5 canvas element. During development, I ran into a performance issue. The number of circles drew went up almost exponentially at one point and so the performance went down (exponentially) at the same time.

The performance issue itself has since been solved by other means, but when the issue arose, it prompted me to write this little bit of JavaScript code.

I figured I could save some time by calculating 2 * `Math.PI` and placing the result into a variable to be called by a draw circle function, vs. having the code calculate the number every time `drawCircle()` as called. So... I wrote a quick script, the results were counter intuitive to me... so I thought I'd share them.

## Using the Code

I'm going to illustrate the entirety of the script (it's fairly small) so you can run this on your own. You can take the sections of code I place here and either dump it in an HTML file between `<script></script>` tags or a separate .js file... as you wish.

The script itself creates the `Canvas` element, so there really aren't any HTML requirements besides having an empty HTML page.

First, let's go ahead and set up our canvas and then create our context:

This will give us something to draw on...

JavaScript
```// Create a canvas element.
var canvas = document.createElement("canvas");
canvas.width = 200;
canvas.height = 200;
document.body.appendChild(canvas);
// Set the context
var ctx = canvas.getContext("2d");```

Now, let's create some basic variables to control the test and hold the results:

JavaScript
```// Some basic variables for time tracking and loop
// control.
var startTime;                 //Time each loop starts
var timeList = new Array();    //Array to store the time difference between start and end
var timeList2 = new Array();   //Same as above for the second loop
var circleDraws = 1000;        //How many times to draw a circlce per test set
var testLoops = 10;            //How many times to run the circle test loops
var preCalcTP = 6.28318530718  //Pre Calculated 2*Math.PI```

Create a function to draw a circle:

JavaScript
```//Draws a simple circle
//tpr = 2 * pi (where we normally would put 2*Math.PI
var drawCircle = function(tpr) {
ctx.beginPath();
ctx.arc(50,50,50,0,tpr);
ctx.stroke();
};```

Put some loops in place to draw the circles:

JavaScript
```//First test set where we test if putting the
//previously calculated 6.28318530718
for (x = 0; x < testLoops; x++){
//Clear the canvas
ctx.clearRect(0,0,canvas.width,canvas.height);
//Capture the start time
startTime = Date.now();
//Draw a circle i times
for (i = 0; i <= circleDraws; i++)
{
drawCircle(preCalcTP);
}
//Capture the time difference in an array
timeList.push(Date.now() - startTime)
}

//Second test set where we put in the normal
//Math.PI * 2
for (x = 0; x < testLoops; x++){
//Clear the Canvas
ctx.clearRect(0,0,canvas.width,canvas.height);
//Capture the start time
startTime = Date.now();
//Draw a circle i times.
for (i = 0; i <= circleDraws; i++)
{
//Draw the circle
drawCircle(2*Math.PI);
}
//Capture the time difference
timeList2.push(Date.now() - startTime)
}```

And finally... let's display the results:

JavaScript
```//Start a simple HTML table to pack the results.
"Calculated</th><th>Calculated</th><" +

//Pack a td with a value
var packTD = function(value) {
if (value != null) {
return "<td>" + value + "</td>";
} else {
return "<td>&nbsp;</td>";
}
};

//calculate and format the results
for (i = 0; i < timeList.length; i++)
{
//New Row for the Result Table
resultTable += "<tr>";
//Append the Pre-Calculated time to the row
resultTable += packTD(timeList[i]);
//Append the Calculated time to the row
resultTable += packTD(timeList2[i]);
//Append the Difference
resultTable += packTD(timeList[i] - timeList2[i]);
//Close the New Row
resultTable += "</tr>";
}

//Close the result table
resultTable += "</tbody></table>";

//Display the results
var tableResults = document.createElement("tableResults");
tableResults.innerHTML = resultTable;
document.body.appendChild(tableResults);```

## Points of Interest

You'll see that after running this little script a few times, a pattern starts to emerge.

1. Using `Math.PI * 2` is faster than using a `var` with the number already calculated (which is odd to me).
2. The performance for each run goes up and down by about 30-50% each time you run it (for either set of test).

Take a look at the result table below to see what I mean.

 Pre-Calculated Calculated Difference 133 85 48 82 161 -79 161 84 77 85 160 -75 160 87 73 85 158 -73 84 87 -3 158 162 -4 84 87 -3 161 156 5

I just thought the results were interesting and that I would share... enjoy!

## Share

 Architect United States
Developing software since 1995, starting out with Borland Turbo C++ 3 & Motorolla Assembly.
Eventually learning several different languages such as
Pascal/Delphi,Basic, Visual Basic,FoxPro, ASP, PHP, and Perl.

Currently using the .net framework for most development task.

Hobbies include underwater robotics, and electronics.

George's current language of choice is C#.

 First Prev Next
 My vote of 2 VMAtm7-Nov-13 21:57 VMAtm 7-Nov-13 21:57
 Test invalid BloodBaz29-Oct-13 1:35 BloodBaz 29-Oct-13 1:35
 My vote of 1 BloodBaz29-Oct-13 1:33 BloodBaz 29-Oct-13 1:33
 My vote of 1 SteveScanlon28-Oct-13 6:26 SteveScanlon 28-Oct-13 6:26
 More research required SteveScanlon28-Oct-13 6:23 SteveScanlon 28-Oct-13 6:23
 Re: More research required George H. Slaterpryce III28-Oct-13 7:26 George H. Slaterpryce III 28-Oct-13 7:26
 Re: More research required Member 190975729-Oct-13 2:26 Member 1909757 29-Oct-13 2:26
 Last Visit: 31-Dec-99 18:00     Last Update: 27-Jul-21 17:54 Refresh 1