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
Sort by number (without mutation)
const items = Array.from({ length: 1e3 }).map((_, index) => {
const publishedAt = Math.floor(Date.now() * Math.random())
return {
publishedAt,
name: 'Article ' + index }
})
const sortByNumber = (items, key) => {
const l = items.length
const b = 32 - Math.clz32(l)
const m = (1 << b) - 1
const tmp = new Float64Array(l)
const res = Array(l)
let i = l
let j = l
while (i--) {
const item = items[i]
const v = item[key]
if (typeof v === 'number') {
tmp[i] = (v << b) | i
} else {
res[--j] = item
}
}
const sorted = tmp.subarray(0, j).sort()
while (j--) {
res[j] = items[sorted[j] & m]
}
return res
}
const sortByNumberMath = (items, key) => {
const l = items.length
const tmp = new Float64Array(l)
const res = Array(l)
let i = l
let j = l
while (i--) {
const item = items[i]
const v = item[key]
if (typeof v === 'number') {
tmp[i] = v * l + i
} else {
res[--j] = item
}
}
const sorted = tmp.subarray(0, j).sort()
while (j--) {
res[j] = items[sorted[j] % l]
}
return res
}
const sortByNumberExp = (items, key) => {
const l = items.length
const b = 32 - Math.clz32(l)
const x = Math.pow(2, b)
const tmp = new Float64Array(l)
const res = Array(l)
let i = l
let j = l
while (i--) {
const item = items[i]
const v = item[key]
if (typeof v === 'number') {
tmp[i] = v * x + i
} else {
res[--j] = item
}
}
const sorted = tmp.subarray(0, j).sort()
while (j--) {
res[j] = items[sorted[j] % l]
}
return res
}
const sortByNumberBigInt = (items, key) => {
const l = items.length
const b = 32 - Math.clz32(l)
const m = BigInt((1 << b) - 1)
const tmp = new Float64Array(l)
const res = Array(l)
let i = l
let j = l
while (i--) {
const item = items[i]
const v = item[key]
if (typeof v === 'number') {
tmp[i] = Number((BigInt(v) << BigInt(b)) | BigInt(i))
} else {
res[--j] = item
}
}
const sorted = tmp.subarray(0, j).sort()
while (j--) {
res[j] = items[Number(BigInt(sorted[j]) & m)]
}
return res
}
const sortByNumberAlt = (items, key) => {
const l = items.length
const b = 32 - Math.clz32(l)
const m = (1 << b) - 1
const tmp = new Float64Array(l)
const res = Array(l)
let i = l
let j = l
while (i--) {
const item = items[i]
const v = item[key]
if (typeof v === 'number') {
tmp[i] = v * 2 ** b + i
} else {
res[--j] = item
}
}
const sorted = tmp.subarray(0, j).sort()
while (j--) {
res[j] = items[sorted[j] % (1 << b)]
}
return res
}
const sortByNumberMathOrBits = (items, key) => {
const l = items.length
const b = 32 - Math.clz32(l)
const m = (1 << b) - 1
const tmp = new Float64Array(l)
const res = Array(l)
let i = l
let j = l
while (i--) {
const item = items[i]
const v = item[key]
if (typeof v === 'number') {
tmp[i] = Math.clz32(v) < b ? v * 2 ** b + i : (v << b) | i
} else {
res[--j] = item
}
}
const sorted = tmp.subarray(0, j).sort()
while (j--) {
const v = sorted[j]
res[j] = items[v >>> 0 === v ? v & m : v % (1 << b)]
}
return res
}
const sortByBigInt = (items, key) => {
const l = items.length
const b = BigInt(32 - Math.clz32(l))
const m = (1n << b) - 1n
const tmp = new BigInt64Array(l)
const res = Array(l)
let i = l
let bi = BigInt(l)
let j = l
while (i--) {
const item = items[i]
const v = item[key]
bi--
if (typeof v === 'number') {
tmp[i] = (BigInt(v) << b) | bi
} else {
res[--j] = item
}
}
const sorted = tmp.subarray(0, j).sort()
while (j--) {
res[j] = items[Number(sorted[j] & m)]
}
return res
}
Ready to run.
Test | Ops/sec | |
---|---|---|
native sort |
| ready |
native toSorted |
| ready |
sortByNumber |
| ready |
sortByNumberMath |
| ready |
sortByNumberExp |
| ready |
sortByNumberBigInt |
| ready |
sortByNumberAlt |
| ready |
sortByNumberMathOrBits |
| ready |
sortByBigInt |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.