Udacity-optimise-loop-test (v2)

Revision 2 of this benchmark created by ro on


Description

For udacity optimise course

Preparation HTML

<div id="movingPizzas1">

</div>
<script>
function createBGPizza() {
  var cols = 8;
  var s = 256;

  for (var i = 0; i < 50; i++) { // Generating pizzas based on screen size instead of a default 200.
    var elem = document.createElement('img');
    elem.className = 'mover'
    elem.src = "http://ro-savage.github.io/udacity-optimise/views/images/pizza.png"; // Stop the browser from resizing image
    elem.style.height = "100px";
    elem.style.width = "73.333px";
    elem.style.position = "fixed";
    elem.style.transform = "translate3d(0, 0, 0)";
    //elem.style.webkitBackfaceVisibility = "hidden";
    //elem.style.webkitPerspective = "1000";
    elem.style.backfaceVisibility = "hidden";
    elem.style.perspective = "1000";
    elem.phase = i % 5; // Added a phase number here when it was created to be looked up later
    elem.basicLeft = (i % cols) * s; // Replaced with above, simplify the formula in movement loop.
    elem.style.top = (Math.floor(i / cols) * s) + 'px';
    document.querySelector("#movingPizzas1").appendChild(elem);
  }
};

createBGPizza();
</script>

Setup

var randomScrollTop = Math.random() * 10000;

Test runner

Ready to run.

Testing in
TestOps/sec
Original code
var items = document.querySelectorAll('.mover');
  for (var i = 0; i < items.length; i++) {
    var phase = Math.sin((randomScrollTop / 1250) + (i % 5));
    items[i].style.left = items[i].basicLeft + 100 * phase + 'px';
  }
ready
Calculate phase in loop
  var phaseInt = randomScrollTop / 1250;

  var items = document.querySelectorAll('.mover');

  // cache length as it won't change during a single loop
  var l = items.length;

  for (var i = 0; i < l; i++) {
    //Work out movement
    var phase = Math.sin(phaseInt + i % 5) * 100;

    // Using translate to allow faster painting and rendering.
    items[i].style.transform = 'translateX(' + phase + 'px)';
  }
ready
Calculate phase outside loop and query object
  var phaseInt = randomScrollTop / 1250;

  // Create phase out of loop and put in an array to be looked up later
  var phases = [];
  phases.push(Math.sin(phaseInt + 0) * 100);
  phases.push(Math.sin(phaseInt + 1) * 100);
  phases.push(Math.sin(phaseInt + 2) * 100);
  phases.push(Math.sin(phaseInt + 3) * 100); 
  phases.push(Math.sin(phaseInt + 4) * 100);

  var items = document.querySelectorAll('.mover');

  // cache length as it won't change during a single loop
  var l = items.length;

  for (var i = 0; i < l; i++) {

    // Use the special phase property added during creation of object to find correct phase from array
    items[i].style.transform = 'translateX(' + phases[items[i].phase] + 'px)';
  }
ready
Original using transform
var items = document.querySelectorAll('.mover');
  for (var i = 0; i < items.length; i++) {
    var phase = Math.sin((randomScrollTop / 1250) + (i % 5));
    items[i].style.transform = 'translateX(' + (items[i].basicLeft + 100) * phase + 'px)'; // using transform for better performance comparison
  }
 
ready
Original using transform without basicLeft lookup
var items = document.querySelectorAll('.mover');
  for (var i = 0; i < items.length; i++) {
    var phase = Math.sin((randomScrollTop / 1250) + (i % 5));
    items[i].style.transform = 'translateX(' + 100 * phase + 'px)'; // using transform for better performance comparison
  }
ready
Calculate Phase in loop - basic left
var phaseInt = randomScrollTop / 1250;
var items = document.querySelectorAll('.mover');
var l = items.length;

  for (var i = 0; i < l; i++) {
    var phase = Math.sin(phaseInt + i % 5);

    items[i].style.left = items[i].basicLeft + 100 * phase + 'px';
  }
ready
Loop Concise
  var items = document.querySelectorAll('.mover'); // Chache items
  var len = items.length; // Cache length
  var phaseInt = randomScrollTop / 1250; // Move calulation out of loop

  for (var i = 0; i < len; i++) {
    var move = Math.sin(phaseInt + (i % 5)) * 100 + items[i].basicLeft; // calculations are done individually
    items[i].style.left = move + 'px';
  }
 
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.