jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
This is an edited test from http://jsperf.com/jqm3/26 by @DevinRhode2
I added a raw JS baseline, and another test that uses javascript prototypes to create some jquery-like abstraction, but yield nearly the same performance as raw JS. This makes one consider the Prototype javascript library. In attempting to add the Prototype version, I decided that it's too different, even as a pretty well versed javascript developer.
From: http://api.prototypejs.org/dom/Element/new/, a Prototype test case would look something like this:
var ul = new Element('ul').update("<li>Hello PrototypeJS world, you're strange.");
.update? .text or .innerText are far too commonplace, and .update truly threw me for a second. PrototypeJS is great, but I'd rather see a jQ.Mobi re-write that heavily uses prototypes of native objects. By my investigation on their docs site, prototypes don't seem modified at all. I'm curious about the feasibility of a jQ.Mobi re-write that heavily uses prototypes
<script src="//zeptojs.com/zepto.min.js"></script>
<script src="//cdn.jqmobi.com/jq.mobi.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
var activeNodes = [];
var backgroundColor = '#000';
var clock = null;
var offColor = '#333';
var onColor = '#fff';
var runAlways = null;
var runOnce = null;
// http://xkcd.com/1123/
function evenThymeIsJustHydrogenAndTime (indices)
{
// console.log('indices', indices);
var hourRow = indices[0];
var row = $('#WordClock *:nth-child(' + hourRow + ')');
var hourLeft = indices[1];
var hourRight = hourLeft + indices[2];
for (var i = hourLeft; i < hourRight; i++)
{
var child = row.children("*:nth-child(" + i + ")");
activeNodes.push(child);
child.css('color', onColor);
child.addClass("on");
}
}
function clickJackAllTheThings (e)
{
var link = $(e.currentTarget);
var newBackgroundColor = link.css('background-color');
if ( newBackgroundColor ) backgroundColor = newBackgroundColor;
var newOffColor = link.data('off-color');
if ( newOffColor ) offColor = newOffColor;
// var newOnColor = link.data('on-color');
var newOnColor = link.css('color');
if ( newOnColor ) onColor = newOnColor;
clock.css({
'background-color': backgroundColor,
'color': offColor
});
// update the highlighted nodes
for (var n = 0; n < activeNodes.length; n++)
{
activeNodes[n].css('color', onColor);
}
}
function setCurrentTime ()
{
//establish what the time is
var currentTime = new Date();
var hour = currentTime.getHours() - 1;
if(hour == -1){ hour = 11; }
var minute = currentTime.getMinutes();
var ampm = "am";
if(hour > 11){
ampm = "pm";
hour = hour-12;
}
if(hour == 11){
ampm = "pm";
}
// un-highlight prior active nodes
for (var n = 0; n < activeNodes.length; n++)
{
activeNodes[n].css('color', offColor);
activeNodes[n].removeClass("on");
}
// highlight the hour
evenThymeIsJustHydrogenAndTime(hours[hour]);
// highlight the minute's ones
var minTen = Math.floor(minute / 10);
var minOne = (minute % 10);
// handle tens and teens in a special manner
// 10, 11, and 12 => treated as extra "ones", with no "tens"
// 13+ => treated as extra "ones", includes the "ten"
if ( minTen == 1 )
{
minTen = (minOne < 3 ? 0 : 1);
minOne += 10;
}
// highlight the minute's "ones"
// if an even multiple of 10 minutes, skip the "ones"
if ( ! (minTen && minOne == 0) )
{
evenThymeIsJustHydrogenAndTime(minOnes[minOne]);
}
// highlight the minute's "tens"
// handle 10, 11, 12 in a special manner (see above)
if ( minOne < 10 || minOne > 12 )
{
evenThymeIsJustHydrogenAndTime(minTens[minTen]);
}
// this method has been run once before
// assume we're at the "top of the minute" now
// clear the one-time interval and setup the per-minute interval
if ( runOnce )
{
// clear the one-time interval
clearInterval(runOnce)
// set the interval to run every minute
runAlways = setInterval(setCurrentTime, 60000);
}
// run this function again at the top of the minute
// but only do this ONCE!
else
{
var currentTime = new Date();
var second = currentTime.getSeconds();
nextInterval = Math.max((60 - second), 1);
runOnce = setInterval(setCurrentTime, (nextInterval * 1000));
}
}
/*
Link-lists below define grid positions for the various words on the clock
*/
var hours = [
// row, left, len
[ 1, 1, 3 ], // one
[ 2, 1, 3 ], // two
[ 1, 4, 5 ], // three
[ 2, 4, 4 ], // four
[ 1, 9, 4 ], // five
[ 3, 1, 3 ], // six
[ 2, 8, 5 ], // seven
[ 3, 4, 5 ], // eight
[ 3, 9, 4 ], // nine
[ 5, 1, 3 ], // ten
[ 4, 1, 6 ], // eleven
[ 4, 7, 6 ] // twelve
];
var minTens = [
// row, left, len
[ 8, 6, 1 ], // o
[ 12, 8, 5 ], // -teen
[ 6, 1, 6 ], // twenty
[ 7, 1, 6 ], // thirty
[ 7, 8, 5 ], // forty
[ 8, 1, 5 ] // fifty
];
var minOnes = [
// row, left, len
[ 8, 7, 6 ], // ’clock
[ 9, 1, 3 ], // one
[ 10, 1, 3 ], // two
[ 9, 4, 5 ], // three
[ 10, 4, 4 ], // four
[ 9, 9, 4 ], // five
[ 11, 1, 3 ], // six
[ 10, 8, 5 ], // seven
[ 11, 4, 5 ], // eight
[ 11, 9, 4 ], // nine
[ 5, 10, 3 ], // ten
[ 12, 1, 6 ], // eleven
[ 6, 7, 6 ], // twelve
[ 7, 1, 5 ], // thirteen
[ 10, 4, 4 ], // fourteen
[ 8, 1, 3 ], // fifteen
[ 11, 1, 3 ], // sixteen
[ 10, 8, 5 ], // seventeen
[ 11, 4, 5 ], // eighteen
[ 11, 9, 4 ] // nineteen
];
</script>
<article id="WordClock">
<section>
<div>O</div>
<div>N</div>
<div>E</div>
<div>T</div>
<div>H</div>
<div>R</div>
<div>E</div>
<div>E</div>
<div>F</div>
<div>I</div>
<div>V</div>
<div>E</div>
</section>
<section>
<div>T</div>
<div>W</div>
<div>O</div>
<div>F</div>
<div>O</div>
<div>U</div>
<div>R</div>
<div>S</div>
<div>E</div>
<div>V</div>
<div>E</div>
<div>N</div>
</section>
<section>
<div>S</div>
<div>I</div>
<div>X</div>
<div>E</div>
<div>I</div>
<div>G</div>
<div>H</div>
<div>T</div>
<div>N</div>
<div>I</div>
<div>N</div>
<div>E</div>
</section>
<section>
<div>E</div>
<div>L</div>
<div>E</div>
<div>V</div>
<div>E</div>
<div>N</div>
<div>T</div>
<div>W</div>
<div>E</div>
<div>L</div>
<div>V</div>
<div>E</div>
</section>
<section>
<div>T</div>
<div>E</div>
<div>N</div>
<div>T</div>
<div>E</div>
<div>E</div>
<div>L</div>
<div>F</div>
<div>M</div>
<div>T</div>
<div>E</div>
<div>N</div>
</section>
<section>
<div>T</div>
<div>W</div>
<div>E</div>
<div>N</div>
<div>T</div>
<div>Y</div>
<div>T</div>
<div>W</div>
<div>E</div>
<div>L</div>
<div>V</div>
<div>E</div>
</section>
<section>
<div>T</div>
<div>H</div>
<div>I</div>
<div>R</div>
<div>T</div>
<div>Y</div>
<div>Z</div>
<div>F</div>
<div>O</div>
<div>R</div>
<div>T</div>
<div>Y</div>
</section>
<section>
<div>F</div>
<div>I</div>
<div>F</div>
<div>T</div>
<div>Y</div>
<div>O</div>
<div>’</div>
<div>C</div>
<div>L</div>
<div>O</div>
<div>C</div>
<div>K</div>
</section>
<section>
<div>O</div>
<div>N</div>
<div>E</div>
<div>T</div>
<div>H</div>
<div>R</div>
<div>E</div>
<div>E</div>
<div>F</div>
<div>I</div>
<div>V</div>
<div>E</div>
</section>
<section>
<div>T</div>
<div>W</div>
<div>O</div>
<div>F</div>
<div>O</div>
<div>U</div>
<div>R</div>
<div>S</div>
<div>E</div>
<div>V</div>
<div>E</div>
<div>N</div>
</section>
<section>
<div>S</div>
<div>I</div>
<div>X</div>
<div>E</div>
<div>I</div>
<div>G</div>
<div>H</div>
<div>T</div>
<div>N</div>
<div>I</div>
<div>N</div>
<div>E</div>
</section>
<section>
<div>E</div>
<div>L</div>
<div>E</div>
<div>V</div>
<div>E</div>
<div>N</div>
<div>X</div>
<div>—</div>
<div>T</div>
<div>E</div>
<div>E</div>
<div>N</div>
</section>
</article>
activeNodes = [];
backgroundColor = '#000';
offColor = '#333';
onColor = '#fff';
runOnce = null;
clearInterval(runAlways);
for (var n = 0; n < activeNodes.length; n++)
{
activeNodes[n].css('color', offColor);
activeNodes[n].removeClass("on");
}
Ready to run.
Test | Ops/sec | |
---|---|---|
jQ.Mobi |
| ready |
jQuery |
| ready |
Zepto |
| ready |
Raw JS - Building DOM nodes |
| ready |
some jQuery style, native performance with prototypes |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.