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
var QueryUtil = {
query: function(data, options) {
let result = data || [];
if (!options) {
return result;
}
// filter first
if (options.filter) {
result = QueryUtil.filter(result, options.filter);
}
// search second
if (options.search) {
result = QueryUtil.search(result, options.search);
}
// sort last
if (options.sort) {
QueryUtil.sort(result, options.sort);
}
if (options.search) {
// always sort on searchscore matches when there's a search query
QueryUtil.sort(result, {_searchScore: 'descending'});
}
return result;
},
filter: function(items, filters) {
const filterKeys = Object.keys(filters);
const filterFunctions = {};
filterKeys.forEach((key) => {
switch (typeof filters[key]) {
case 'function':
filterFunctions[key] = filters[key];
break;
case 'string':
default:
filterFunctions[key] = (value) => value === (filters[key]);
break;
}
});
return items.filter((item) => {
let match = 0;
filterKeys.forEach((key) => {
if (filterFunctions[key](item[key])) {
match++;
}
});
return match === filterKeys.length;
});
},
sort: function(items, sorting) {
items.sort(QueryUtil._multipleCompare(Object.keys(sorting), sorting));
return items;
},
_multipleCompare: function(sortKeys, sorting) {
return (a, b) => {
let result;
let aValue;
let bValue;
sortKeys.some((key) => {
// NOTE: valueOf() allows for sorting of dates
aValue = (a[key] !== null) ? a[key].valueOf() : null;
bValue = (b[key] !== null) ? b[key].valueOf() : null;
result = (typeof sorting[key] === 'function') ? sorting[key](aValue, bValue) : QueryUtil._getCompareResult(aValue, bValue, sorting[key] === 'descending');
// NOTE: keep sorting as long as value is 0 (equal) otherwise stop,
// this allows multiple property sort
return result !== 0;
});
return result;
};
},
_getCompareResult: function(aValue, bValue, descending) {
if (aValue !== bValue) {
return !!descending === (aValue === null || aValue > bValue) ? -1 : 1;
}
return 0;
},
search: function(items, search) {
const searchKeys = Object.keys(search);
const searchFunctions = {};
searchKeys.forEach((key) => {
switch (typeof search[key]) {
case 'string':
searchFunctions[key] = (value) => (value.match(new RegExp(search[key], 'gi')) || []).length;
break;
case 'function':
default:
searchFunctions[key] = search[key];
}
});
return items.filter((item) => {
item._searchScore = 0;
searchKeys.forEach((key) => {
// searchfunction should return occurences
item._searchScore += item[key] ? searchFunctions[key](item[key]) : 0;
});
return !!item._searchScore;
});
}
};
var data = [];
var items = 20000;
var titles = ['stringA', 'stringB', 'stringC', 'stringD'];
var titleMod = titles.length;
var descriptions = ['descriptionAA', 'descriptionBB', 'descriptionCC'];
var descriptionMod = descriptions.length;
for (var i = 0; i < items; i++) {
data.push({
id: i,
title: titles[i % titleMod],
description: descriptions[i % descriptionMod],
});
}
Ready to run.
Test | Ops/sec | |
---|---|---|
filter |
| ready |
filter and sort |
| ready |
search |
| ready |
search filter sort |
| ready |
double filter & multi sort |
| ready |
search and sort |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.