|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<title>canvas performance</title> |
|
<style> |
|
body { |
|
margin: 0; |
|
} |
|
div { |
|
position: absolute; |
|
top: 0px; |
|
left: 0px; |
|
} |
|
</style> |
|
<body> |
|
<canvas width="960" height="500"></canvas> |
|
<script src="//d3js.org/d3.v4.min.js"></script> |
|
<script> |
|
|
|
// # of points to draw |
|
var n = 5000; |
|
|
|
var fmt = d3.format(",d"); |
|
|
|
var canvas = d3.select("canvas").node(); |
|
var context = canvas.getContext("2d"); |
|
var width = canvas.width, height = canvas.height; |
|
|
|
var x = d3.scaleLinear().range([0, width]), |
|
y = d3.scaleLinear().range([height, 0]); |
|
|
|
var info = d3.select('body').append('div') |
|
.style('position', 'absolute') |
|
.style('top', '0') |
|
.style('left', '0') |
|
.style('padding', '5px') |
|
.style('background-color', '#aaa') |
|
|
|
var start = d3.now(), t0 = 0, sum = 0, cnt = 0; |
|
addPoints(t0); |
|
|
|
function addPoints(t) { |
|
var fps = 1000 / (t - t0); |
|
if (t !== 0) { sum += fps; cnt++ }; |
|
info.html(fmt(fps) + " fps for " + fmt(n) +' points = ' + fmt(n * fps) + ' dots/sec'); |
|
console.log('cnt, sec/frame', cnt, 1 / fps) |
|
|
|
// Stop after 30 seconds |
|
if (t > 30 * 1000) return finalTime(t); |
|
|
|
context.clearRect(0, 0, width, height); |
|
context.beginPath(); |
|
for (var i = 0, px, py; i < n; ++i) { |
|
px = x(Math.random()), py = y(Math.random()); |
|
if (px < 0 || py < 0 || px > width || py > height) console.log('bad', i, px, py) |
|
context.moveTo(px + 2.5, py); |
|
context.arc(px, py, 2.5, 0, 2 * Math.PI); |
|
} |
|
context.fill(); |
|
|
|
t0 = t; |
|
requestAnimationFrame(addPoints) |
|
} |
|
|
|
function finalTime(t) { |
|
var dt = (d3.now() - start) / 1000; // Total elapsed time (seconds), including startup |
|
var fps = cnt / dt; // Average FPS, including startup |
|
info.html(fmt(fps) + " fps for " + fmt(n) |
|
+ ' points = ' + fmt(n * fps) + ' dots/sec' |
|
+ ', initial startup: ' + fmt(dt - t / 1000)); |
|
} |
|
|
|
</script> |