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
let basic_obj = {
a: true,
b: ["a", "b", "cdef"],
c: {
d: new Map([
["a", 1],
["b", 1],
]),
},
};
let tricky_obj = {
a: new Map([
["@Array", 1],
[{ _meta: "@Array" }, 1],
]),
"@Set": new Set([[{ _meta: 1 }], [{ _meta: 2 }]]),
};
let long_array = ["@Array"];
for(let i = 0; i<10000; i++) {
long_array.push(i);
}
function make_large_object(c = 4) {
if (c <= 0) {
return Math.random();
}
// Large arrays
// Large nested objects
let variants = [
"object",
"evil-object",
"array",
"evil-array",
"map",
"number",
"string",
];
let variant = variants[Math.floor(Math.random() * variants.length)];
if (variant == "object" || variant == "evil-object") {
let size = Math.floor(Math.random() * 10);
let obj = {};
if (variant == "evil-object") {
obj["_meta"] = 3;
}
for (let i = 0; i < size; i++) {
obj[make_large_object(c - 1)] = make_large_object(c - 1);
}
return obj;
} else if (variant == "array" || variant == "evil-array") {
let size = Math.floor(Math.random() * 500);
let arr = [];
if (variant == "evil-array") {
arr.push("@Map");
}
for (let i = 0; i < size; i++) {
arr.push(make_large_object(c - 3));
}
return arr;
} else if (variant == "map") {
let size = Math.floor(Math.random() * 100);
let map = new Map();
for (let i = 0; i < size; i++) {
map.set(make_large_object(c - 2), make_large_object(c - 2));
}
return map;
} else if (variant == "number") {
return Math.random();
} else if (variant == "string") {
return Math.random().toString(36).substring(7);
} else {
throw "Unknown variant";
}
}
let large_objects = [];
for (let i = 0; i < 10; i++) {
large_objects.push(make_large_object());
}
function jsonMapSetReplacer(_, value_) {
if (typeof value_ === "object") {
if (value_ instanceof Map) {
value_ = Array.from(value_);
value_.unshift("@Map");
} else if (value_ instanceof Set) {
value_ = Array.from(value_);
value_.unshift("@Set");
} else if (
Array.isArray(value_) &&
value_.length > 0 &&
(value_[0] === "@Map" ||
value_[0] === "@Set" ||
value_[0] === "@Array")
) {
value_ = value_.slice();
value_.unshift("@Array");
}
}
return value_;
}
function jsonMapSetReviver(_, value_) {
if (typeof value_ === "object") {
if (Array.isArray(value_) && value_.length > 0) {
var isMap, isSet;
if (
(isMap = value_[0] === "@Map") ||
(isSet = value_[0] === "@Set") ||
value_[0] === "@Array"
) {
value_.shift();
if (isMap) value_ = new Map(value_);
else if (isSet) value_ = new Set(value_);
}
}
}
return value_;
}
function stringifyReplacer(key, value) {
if (typeof value === "object" && value !== null) {
if (value instanceof Map) {
return {
_meta: { type: "map" },
value: Array.from(value.entries()),
};
} else if (value instanceof Set) {
// bonus feature!
return {
_meta: { type: "set" },
value: Array.from(value.values()),
};
} else if ("_meta" in value) {
// Escape "_meta" properties
return {
...value,
_meta: {
type: "escaped-meta",
value: value["_meta"],
},
};
}
}
return value;
}
function parseReviver(key, value) {
if (typeof value === "object" && value !== null) {
if ("_meta" in value) {
if (value._meta.type === "map") {
return new Map(value.value);
} else if (value._meta.type === "set") {
return new Set(value.value);
} else if (value._meta.type === "escaped-meta") {
// Un-escape the "_meta" property
return {
...value,
_meta: value._meta.value,
};
} else {
console.warn("Unexpected meta", value._meta);
}
}
}
return value;
}
function jsonMapSetReplacer2 (_, value_) {
if (typeof (value_) === 'object') {
if (value_ instanceof Map) {
value_ = Array.from (value_);
value_.unshift ('@Map');
}
else if (value_ instanceof Set) {
value_ = Array.from (value_);
value_.unshift ('@Set');
}
else if (Array.isArray (value_) && value_.length > 0 &&
(value_ [0] === '@Map' || value_ [0] === '@Set' || value_ [0] === '@Array')) {
value_ = value_.slice ();
value_.unshift ('@Array');
}
}
return value_;
}
function jsonMapSetReviver2 (_, value_) {
if (Array.isArray (value_) && value_.length > 0) {
let isMap, isSet;
if ((isMap = value_ [0] === '@Map') || (isSet = value_ [0] === '@Set') || value_ [0] === '@Array') {
value_.shift ();
if (isMap)
value_ = new Map (value_);
else if (isSet)
value_ = new Set (value_);
}
}
return value_;
}
Ready to run.
Test | Ops/sec | |
---|---|---|
Array Based |
| ready |
Map Based |
| ready |
Array Based |
| ready |
Map Based |
| ready |
Array Based |
| ready |
Map Based |
| ready |
Array Based |
| ready |
Map Based |
| ready |
Array Based 2 |
| ready |
Array Based 2 |
| ready |
Array Based 2 |
| ready |
Array Based 2 |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.