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
Compares two local JSON databases
<script>
var user = {
firstName: "Tila",
lastName: "Tequilla",
city: "Los Angeles",
country: "USA"
};
var users = [];
for (var i = 0; i < 10000; i++) {
var userString = JSON.stringify(user);
users.push(JSON.parse(userString));
}
var Lawnchair = function(a) {
this.init(a)
};
Lawnchair.prototype = {
init: function(a) {
var b = {
webkit: window.WebkitSQLiteAdaptor,
gears: window.GearsSQLiteAdaptor,
dom: window.DOMStorageAdaptor,
cookie: window.CookieAdaptor,
air: window.AIRSQLiteAdaptor,
userdata: window.UserDataAdaptor,
"air-async": window.AIRSQLiteAsyncAdaptor,
blackberry: window.BlackBerryPersistentStorageAdaptor,
couch: window.CouchAdaptor
};
this.adaptor = new DOMStorageAdaptor(a);
if (!JSON || !JSON.stringify) throw "Native JSON functions unavailable - please include http://www.json.org/json2.js or run on a decent browser :P";
},
save: function(a, b) {
this.adaptor.save(a, b)
},
get: function(a, b) {
this.adaptor.get(a, b)
},
exists: function(a) {
this.adaptor.exists(a)
},
all: function(a) {
this.adaptor.all(a)
},
remove: function(a, b) {
this.adaptor.remove(a, b)
},
nuke: function(a) {
this.adaptor.nuke(a);
return this
},
paged: function(a, b) {
this.adaptor.paged(a, b)
},
find: function(a, b) {
var e = typeof a == "string" ?
function() {
return eval(a)
} : a,
d = this.adaptor.terseToVerboseCallback(b);
this.each(function(a, b) {
e(a) && d(a, b)
})
},
each: function(a) {
var b = this.adaptor.terseToVerboseCallback(a);
this.all(function(a) {
for (var d = a.length, c = 0; c < d; c++) b(a[c], c)
})
}
};
if (typeof TAFFY == "undefined" || !TAFFY) TAFFY = function(d) {
var c = {
template: null
},
f = TAFFY,
b = f.isString(d) ? f.JSON.parse(d) : d,
g = [],
h = function(a, i) {
i = i || c.template;
if (!TAFFY.isNull(i)) for (var e = 0, f = a.length; e < f; e++) b[a[e]] = TAFFY.mergeObj(b[a[e]], i)
},
k = function() {
g = [];
for (var a = 0, i = b.length; a < i; a++) g[g.length] = a
};
k();
var m = {
pickTest: function(a) {
var i = a.indexOf("!") === 0 ? !1 : !0;
i || (a = a.substring(1, a.length));
return {
test: a == "equal" ? "is" : a == "notequal" ? "not" : a == "startswith" ? "starts" : a == "endswith" ? "ends" : a == "greaterthan" ? "gt" : a == "lessthan" ? "lt" : a == "regexppass" ? "regex" : a,
mode: i ? {
s: !0,
f: !1
} : {
s: !1,
f: !0
}
}
},
run: function(a, i, e, b) {
return (a == "regex" ? e.test(i) : a == "lt" ? i < e : a == "gt" ? i > e : a == "lte" ? i <= e : a == "gte" ? i >= e : a == "starts" ? i.indexOf(e) === 0 : a == "ends" ? i.substring(i.length - e.length) == e : a == "like" ? i.toUpperCase().indexOf(e.toUpperCase()) >= 0 : a == "is" ? i == e : a == "has" ? f.has(i, e) : a == "hasAll" ? f.hasAll(i, e) : a == "length" ? m.length(i, e, b) : m[a](i, e)) ? b.s : b.f
},
length: function(a, i, e) {
a = !f.isUndefined(a.length) ? a.length : !f.isUndefined(a.getLength) ? a.getLength() : 0;
if (f.isObject(i)) for (var b in i) if (i.hasOwnProperty(b)) return e = m.pickTest(b), m.run(e.test, a, i[b], e.mode) ? !0 : !1;
return a == i ? e.s : e.f
}
};
(function() {
for (var a in TAFFY) TAFFY.hasOwnProperty(a) && a.indexOf("is") === 0 &&
function(a) {
m["is" + a] = function(e, b) {
return TAFFY["is" + a](e) == b ? !0 : !1
}
}(a.substring(2, a.length))
})();
var l = function(a, b) {
var e = [];
!f.isArray(a) && TAFFY.isNumber(a) ? e[e.length] = a : f.isArray(a) ? e = a : f.isObject(a) ? e = b(a) : !f.isArray(a) && !f.isNumber(a) && (e = g);
return e
},
j = function(a) {
var b = [0],
e = "none";
a += "";
if (!f.isNull(a) && !f.isUndefined(a)) {
for (var c = 0, d = a.length; c < d; c++) {
var g = a.slice(c, c + 1);
f.isNumeric(g) ? e != "number" ? (b[b.length] = g, e = "number") : b[b.length - 1] = b[b.length - 1] + "" + g : e != "string" ? (b[b.length] = g, e = "string") : b[b.length - 1] += g
}
c = 0;
for (d = b.length; c < d; c++) f.isNumeric(b[c]) && (b[c] = parseFloat(b[c]))
} else b[b.length] = null;
return b
},
r = function(a) {
var c = [],
e = [];
f.isString(a) ? e[0] = a : e = f.isObject(a) ? [a] : a;
if (f.isArray(e)) {
a = 0;
for (var d = e.length; a < d; a++) if (f.isString(e[a])) c[c.length] = f.isString(b[0][e[a]]) ? {
sortCol: e[a],
sortDir: "asc",
type: "string"
} : {
sortCol: e[a],
sortDir: "asc",
type: "number"
};
else if (f.isObject(e[a])) for (var g in e[a]) e[a].hasOwnProperty(g) && (c[c.length] = f.isString(b[0][e[a].sortCol]) ? {
sortCol: g,
sortDir: e[a][g],
type: "string"
} : {
sortCol: g,
sortDir: e[a][g],
type: "number"
})
}
return function(a, b) {
for (var e = 0, d, g, o = 0, u = c.length; o < u; o++) if (e === 0) if (d = a[c[o].sortCol], g = b[c[o].sortCol], c[o].type == "string" && (d = f.isString(d) ? d.toLowerCase() : d, g = f.isString(g) ? g.toLowerCase() : g), c[o].sortDir == "desc") if (f.isNull(g) || f.isUndefined(g) || g < d) e = -1;
else {
if (f.isNull(d) || f.isUndefined(d) || d < g) e = 1
} else if (c[o].sortDir == "logical") {
d = j(d);
g = j(g);
for (var h = 0, l = g.length; h < l; h++) if (d[h] < g[h] && h < d.length) {
e = -1;
break
} else if (d[h] > g[h]) {
e = 1;
break
}
d.length < g.length && e == 0 ? e = -1 : d.length > g.length && e == 0 && (e = 1)
} else if (c[o].sortDir == "logicaldesc") {
d = j(d);
g = j(g);
h = 0;
for (l = g.length; h < l; h++) if (d[h] > g[h] && h < d.length) {
e = -1;
break
} else if (d[h] < g[h]) {
e = 1;
break
}
d.length < g.length && e == 0 ? e = 1 : d.length > g.length && e == 0 && (e = -1)
} else if (f.isNull(d) || f.isUndefined(d) || d < g) e = -1;
else if (f.isNull(g) || f.isUndefined(g) || d > g) e = 1;
return e
}
};
return {
TAFFY: !0,
getLength: function() {
return b.length
},
lastModifyDate: new Date,
find: function(a, d) {
var e = f.isArray(d) ? d : g;
if (f.isFunction(a)) {
for (var c = [], h = 0, l = e.length; h < l; h++) a(b[h], h) && (c[c.length] = e[h]);
e = c
} else for (var j in a) if (a.hasOwnProperty(j)) {
var k = "is",
n = "",
r = j,
s = {
s: !0,
f: !1
},
q = {};
if (f.isObject(a[j])) for (var t in a[j]) {
if (a[j].hasOwnProperty(t)) q = m.pickTest(t), k = q.test, s = q.mode, n = a[j][t]
} else n = a[j];
c = [];
h = 0;
for (l = e.length; h < l; h++) if (f.isArray(n) && k != "isSameArray" && k != "hasAll") if (s.s) for (var p = 0; p < n.length; p++) m.run(k, b[e[h]][r], n[p], s) && (c[c.length] = e[h]);
else {
q = 1;
for (p = 0; p < n.length; p++) m.run(k, b[e[h]][r], n[p], s) || (q = 0);
q == 1 && (c[c.length] = e[h])
} else f.isFunction(n) && n(b[e[h]][r], h) ? c[c.length] = e[h] : m.run(k, b[e[h]][r], n, s) && (c[c.length] = e[h]);
e = c
}
return e = f.gatherUniques(e)
},
remove: function(a) {
a = l(a, this.find);
for (var c = 0, e = a.length; c < e; c++) {
if (!f.isNull(this.onRemove)) this.onRemove(b[a[c]]);
b[a[c]] = "remove"
}
for (c = function() {
for (var a = 0, e = b.length; a < e; a++) if (b[a] === "remove") return !0;
return !1
}; c();) {
e = 0;
for (var d = b.length; e < d; e++) if (b[e] === "remove") b.splice(e, 1), this.lastModifyDate = new Date
}
k();
return a
},
insert: function(a) {
a = TAFFY.isArray(a) ? a : [a];
for (var d = 0; d < a.length; d++) {
if (!f.isNull(this.onInsert)) this.onInsert(a[d]);
b[b.length] = TAFFY.isNull(c.template) ? a[d] : TAFFY.mergeObj(c.template, a[d]);
this.lastModifyDate = new Date;
g[g.length] = b.length - 1
}
return [b.length - 1]
},
update: function(a, c) {
for (var e =
l(c, this.find), d = 0, g = 0, h = e.length; g < h; g++) {
var j = e[g];
if (!f.isNull(this.onUpdate)) this.onUpdate(a, b[j]);
b[j] = f.mergeObj(b[j], a);
d++
}
return e
},
get: function(a) {
var c = [];
a = l(a, this.find);
for (var e = 0, d = a.length; e < d; e++) c[c.length] = b[a[e]];
return c
},
first: function(a) {
a = l(a, this.find);
return a.length > 0 ? b[a[0]] : !1
},
last: function(a) {
a = l(a, this.find);
return a.length > 0 ? b[a[a.length - 1]] : !1
},
stringify: function(a) {
return f.JSON.stringify(this.get(a))
},
orderBy: function(a) {
if (b.length > 0) a = f.isFunction(a) ? a : r(a), b.sort(a), this.lastModifyDate = new Date
},
forEach: function(a, c) {
for (var e = l(c, this.find), d, g = 0, h = e.length; g < h; g++) if (d = b[e[g]], d = a(d, e[g]), f.isObject(d)) if (TAFFY.isSameObject(d, TAFFY.EXIT)) break;
else this.update(d, e[g])
},
sum: function(a, b) {
var e = 0;
this.forEach(function(b) {
TAFFY.isNumeric(b[a]) && (e += b[a])
}, b);
return e
},
max: function(a, b) {
var e, c = 0;
this.forEach(function(b) {
c == 1 && b[a] > e ? e = b[a] : c == 0 && (e = b[a], c = 1)
}, b);
return e
},
min: function(a, b) {
var c, d = 0;
this.forEach(function(b) {
d == 1 && b[a] < c ? c = b[a] : d == 0 && (c = b[a], d = 1)
}, b);
return c
},
values: function(a, b) {
var c = [];
this.forEach(function(b) {
c[c.length] = b[a]
}, b);
return c
},
uniqueValues: function(a, b) {
var c = TAFFY([]);
this.forEach(function(b) {
c.find({
value: b[a]
}).length == 0 && c.insert({
value: b[a]
})
}, b);
return c.values("value")
},
config: {
set: function(a, b) {
c[a] = b;
a == "template" && !TAFFY.isNull(b) && h(g, b)
},
get: function(a) {
return c[a]
}
},
applyTemplate: function(a, b) {
var c = l(b, this.find);
h(c, a)
},
onUpdate: null,
onRemove: null,
onInsert: null
}
}, TAFFY.typeOf = function(d) {
var c =
typeof d;
c === "object" && (d ? typeof d.length === "number" && !d.propertyIsEnumerable("length") && typeof d.splice === "function" && (c = "array") : c = "null");
return c
}, TAFFY.JSON = function() {
function d(b) {
return b < 10 ? "0" + b : b
}
function c(b, d) {
var h, k, m, l;
h = RegExp('["\\\\\\x00-\\x1f\\x7f-\\x9f]', "g");
var j;
switch (typeof b) {
case "string":
return h.test(b) ? '"' + b.replace(h, function(b) {
var a = f[b];
if (a) return a;
a = b.charCodeAt();
return "\\u00" + Math.floor(a / 16).toString(16) + (a % 16).toString(16)
}) + '"' : '"' + b + '"';
case "number":
return isFinite(b) ? String(b) : "null";
case "boolean":
case "null":
return String(b);
case "object":
if (!b) return "null";
if (typeof b.toJSON === "function") return c(b.toJSON());
h = [];
if (typeof b.length === "number" && !b.propertyIsEnumerable("length")) {
l = b.length;
for (k = 0; k < l; k += 1) h.push(c(b[k], d) || "null");
return "[" + h.join(",") + "]"
}
if (d) {
l = d.length;
for (k = 0; k < l; k += 1) m = d[k], typeof m === "string" && (j = c(b[m], d)) && h.push(c(m) + ":" + j)
} else for (m in b) typeof m === "string" && (j = c(b[m], d)) && h.push(c(m) + ":" + j);
return "{" + h.join(",") + "}"
}
return ""
}
Date.prototype.toJSON =
function() {
return this.getUTCFullYear() + "-" + d(this.getUTCMonth() + 1) + "-" + d(this.getUTCDate()) + "T" + d(this.getUTCHours()) + ":" + d(this.getUTCMinutes()) + ":" + d(this.getUTCSeconds()) + "Z"
};
var f = {
"\u0008": "\\b",
"\t": "\\t",
"\n": "\\n",
"\u000c": "\\f",
"\r": "\\r",
'"': '\\"',
"\\": "\\\\"
};
return {
stringify: c,
parse: function(b, c) {
function d(b, f) {
var j, k;
if (f && typeof f === "object") for (j in f) Object.prototype.hasOwnProperty.apply(f, [j]) && (k = d(j, f[j]), k !== void 0 ? f[j] = k : delete f[j]);
return c(b, f)
}
var f;
if (/^[\],:{}\s]*$/.test(b.replace(/\\./g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) return f = eval("(" + b + ")"), typeof c === "function" ? d("", f) : f;
throw new SyntaxError("parseJSON");
}
}
}(), TAFFY.mergeObj = function(d, c) {
var f = {},
b;
for (b in d) d.hasOwnProperty(b) && (f[b] = d[b]);
for (b in c) c.hasOwnProperty(b) && (f[b] = c[b]);
return f
}, TAFFY.getObjectKeys = function(d) {
var c = [],
f;
for (f in d) d.hasOwnProperty(f) && (c[c.length] = f);
c.sort();
return c
}, TAFFY.isSameArray = function(d, c) {
return TAFFY.isArray(d) && TAFFY.isArray(c) && d.join(",") == c.join(",") ? !0 : !1
}, TAFFY.isSameObject = function(d, c) {
var f = TAFFY;
if (f.isObject(d) && f.isObject(c)) if (f.isSameArray(f.getObjectKeys(d), f.getObjectKeys(c))) for (var b in d) {
if (d.hasOwnProperty(b) && !(f.isObject(d[b]) && f.isObject(c[b]) && f.isSameObject(d[b], c[b]) || f.isArray(d[b]) && f.isArray(c[b]) && f.isSameArray(d[b], c[b]) || d[b] == c[b])) return !1
} else return !1;
else return !1;
return !0
}, TAFFY.has = function(d, c) {
var f = TAFFY,
b = !0;
if (f.isTAFFY(d)) return b = d.find(c), b.length > 0 ? !0 : !1;
else switch (f.typeOf(d)) {
case "object":
if (f.isObject(c)) {
for (var g in c) if (b === !0 && c.hasOwnProperty(g) && !f.isUndefined(d[g]) && d.hasOwnProperty(g)) b = f.has(d[g], c[g]);
else return !1;
return b
} else if (f.isArray(c)) for (g = 0; g < c.length; g++) {
if (b = f.has(d, c[g]), b === !0) return !0
} else if (f.isString(c) && !TAFFY.isUndefined(d[c])) return !0;
break;
case "array":
if (f.isObject(c)) for (var h = 0; h < d.length; h++) {
if (b = f.has(d[h], c), b == !0) return !0
} else if (f.isArray(c)) for (g = 0; g < c.length; g++) for (h = 0; h < d.length; h++) {
if (b = f.has(d[h], c[g]), b == !0) return !0
} else if (f.isString(c)) for (h = 0; h < d.length; h++) if (b = f.has(d[h], c), b == !0) return !0;
break;
case "string":
if (f.isString(c) && c == d) return !0;
break;
default:
if (f.typeOf(d) == f.typeOf(c) && d == c) return !0
}
return !1
}, TAFFY.hasAll = function(d, c) {
var f = TAFFY;
if (f.isArray(c)) {
for (var b = !0, g = 0, h = c.length; g < h; g++) if (b = f.has(d, c[g]), b == !1) return b;
return !0
} else return f.has(d, c)
}, TAFFY.gatherUniques = function(d) {
for (var c = [], f = 0; f < d.length; f++) {
for (var b = !0, g = 0; g < c.length; g++) c[g] == d[f] && (b = !1);
b == !0 && (c[c.length] = d[f])
}
return c
}, function(d) {
for (var c = 0; c < d.length; c++)(function(c) {
TAFFY["is" + c] = function(b) {
return TAFFY.typeOf(b) == c.toLowerCase() ? !0 : !1
}
})(d[c])
}(["String", "Number", "Object", "Array", "Boolean", "Null", "Function", "Undefined"]), TAFFY.isNumeric = function(d) {
for (var c = 0; c < d.length && !0 == !0; c++) if ("0123456789".indexOf(d.charAt(c)) == -1) return !1;
return !0
}, TAFFY.isTAFFY = function(d) {
return TAFFY.isObject(d) && d.TAFFY ? !0 : !1
}, TAFFY.EXIT = {
EXIT: !0
};
localDB = TAFFY;
</script>
Ready to run.
Test | Ops/sec | |
---|---|---|
DB initialisation TAFFY |
| ready |
DB initialisation Lawnchair |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.