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 my attempt to prove the regression in performance that occurred with in 1.4.4, with this commit. I've then applied this plugin to the third test to show how easy it is to bring 1.4.3 performance back into 1.6.
This bug has been closed as "wontfix", for the following stated reason:
Both the createRange and sourceIndex code branches failed on disconnected DOM nodes, nodes in separate DOM documents, and nodes in non-HTML documents. Replacing that code with this yields much better cross-platform results overall.
It should be noted, however that in my tests with disconnected DOM nodes within 1.5.2, all browsers produce nonsensical, and different results upon sorting (including different results within the same browser upon refreshing). Therefore, this change didn't appear to improve the situation for sorting disconnected nodes. I didn't do any tests regarding separate DOM documents (Does this refer to pulling in nodes from an iframe for instance?) nor non-HTML documents. What would be nice though, is test cases that demonstrate the problem. This plugin passes all of the unit tests as of the release of 1.5.2.
I don't deny that sourceIndex could be problematic, however, it's my belief that the performance decrease is severe enough under certain conditions in IE7/8 that we need some method of both preserving the sourceIndex method of sorting where we can, while also addressing whatever testable issues exist with sourceIndex. That would result, unfortunately in more code than was in 1.4.2, rather than less code as was committed, but if jQuery is serious in support for IE 6,7 and 8 serious consideration needs to be made to the performance of those browsers.
update
Volker Mische has added another test case with the current build from git (1.6.1pre) which contains some fixes 1 2 (thanks John Resig).
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>var a = jQuery.noConflict();</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
<script>var b = jQuery.noConflict();</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
<script>
(function($) {
if ("sourceIndex" in document.documentElement) {
var baseHasDuplicate = true,
sortOrder = null;
// Here we check if the JavaScript engine is using some sort of
// optimization where it does not always call our comparision
// function. If that is the case, discard the hasDuplicate value.
// Thus far that includes Google Chrome.
[0, 0].sort(function() {
baseHasDuplicate = false;
return 0;
});
sortOrder = function(a, b) {
if (!a.sourceIndex || !b.sourceIndex) {
if (a == b) {
hasDuplicate = true;
}
return a.sourceIndex ? -1 : 1;
}
var ret = a.sourceIndex - b.sourceIndex;
if (ret === 0) {
hasDuplicate = true;
}
return ret;
};
$.unique = function(results) {
if (sortOrder) {
hasDuplicate = baseHasDuplicate;
results.sort(sortOrder);
if (hasDuplicate) {
for (var i = 1; i < results.length; i++) {
if (results[i] === results[i - 1]) {
results.splice(i--, 1);
}
}
}
}
return results;
};
}
})(jQuery);
var c = jQuery.noConflict();</script>
<script src="http://code.jquery.com/jquery-git.js"></script>
<script>var d = jQuery.noConflict();</script>
<style>
.test {
display: none;
}
</style>
<div id="items">
</div>
<script>
var amt = 50,
$jq_142 = a('#items'),
$jq_16 = b('#items'),
$jq_16_with_fix = c('#items'),
$jq_git = d('#items'),
elems = [];
for (var i = 0; i < amt; i++) {
elems.push('<ul class="test"><li class="test">foo</li></ul>');
elems.push('<div class="test">hmm</div>');
elems.push('<input class="test" type="hidden" name="hoo' + i + '" /> ')
elems.push('<select class="test"><option value="1">foo</option></select>')
}
$jq_142.html(elems.join(""));
$jq_16.html(elems.join(""));
$jq_16_with_fix.html(elems.join(""));
$jq_git.html(elems.join(""));
</script>
Ready to run.
Test | Ops/sec | |
---|---|---|
version 1.4.2 |
| ready |
version 1.6 |
| ready |
1.6 with fix |
| ready |
git |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.