reduce(): 10 x 832,441 ops/sec ±1.11% (87 runs sampled)
reduce(): 100 x 56,307 ops/sec ±1.65% (87 runs sampled)
reduce(): 1,000 x 1,158 ops/sec ±1.58% (88 runs sampled)
reduce() w/ mutate: 10 x 3,144,202 ops/sec ±1.27% (91 runs sampled)
reduce() w/ mutate: 100 x 556,441 ops/sec ±1.08% (94 runs sampled)
reduce() w/ mutate: 1,000 x 67,205 ops/sec ±0.40% (97 runs sampled)
forEach(): 10 x 3,202,435 ops/sec ±0.62% (83 runs sampled)
forEach(): 100 x 597,300 ops/sec ±1.24% (91 runs sampled)
forEach(): 1,000 x 67,361 ops/sec ±1.08% (91 runs sampled)
filter() & map(): 10 x 184,837 ops/sec ±1.18% (89 runs sampled)
filter() & map(): 100 x 15,476 ops/sec ±0.60% (96 runs sampled)
filter() & map(): 1,000 x 346 ops/sec ±1.18% (88 runs sampled)
filter/map w/ pairs: 10 x 171,885 ops/sec ±0.44% (92 runs sampled)
filter/map w/ pairs: 100 x 13,407 ops/sec ±0.78% (89 runs sampled)
filter/map w/ pairs: 1,000 x 402 ops/sec ±1.36% (85 runs sampled)
fromEntries(): 10 x 917,920 ops/sec ±1.34% (87 runs sampled)
fromEntries(): 100 x 122,082 ops/sec ±1.01% (84 runs sampled)
fromEntries(): 1,000 x 12,402 ops/sec ±1.20% (91 runs sampled)
transducers: 10 x 162,910 ops/sec ±0.84% (92 runs sampled)
transducers: 100 x 12,612 ops/sec ±0.58% (95 runs sampled)
transducers: 1,000 x 420 ops/sec ±0.26% (92 runs sampled)
for-of-loop: 10 x 3,109,700 ops/sec ±1.02% (93 runs sampled)
for-of-loop: 100 x 588,851 ops/sec ±1.10% (91 runs sampled)
for-of-loop: 1,000 x 64,205 ops/sec ±0.79% (86 runs sampled)
for-loop: 10 x 3,229,874 ops/sec ±0.31% (94 runs sampled)
for-loop: 100 x 580,379 ops/sec ±1.30% (92 runs sampled)
for-loop: 1,000 x 69,433 ops/sec ±1.28% (90 runs sampled)
-
-
Save tgroshon/3ef57a31f7ccb2d7706d7f8645dcd161 to your computer and use it in GitHub Desktop.
JavaScrpit benchmark: reduce, filter, map(), transducers, and for loops
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { Suite } = require("benchmark"); | |
const { | |
useReduce, | |
useReduceMutate, | |
useForEach, | |
useFilterMap, | |
useFilterMap2, | |
useFromEntries, | |
useTransduce, | |
useForLoop, | |
useForOfLoop | |
} = require("./impls"); | |
console.log("Preparing run..."); | |
function genUsers(n) { | |
let users = []; | |
while (n--) users.push({ active: false, id: n, name: `user ${n}` }); | |
return users; | |
} | |
let users = {}; | |
for (let n of [10, 100, 1000]) users[n] = genUsers(n); | |
let suite = new Suite(); | |
suite.add("reduce(): 10", () => useReduce(users[10])); | |
suite.add("reduce(): 100", () => useReduce(users[100])); | |
suite.add("reduce(): 1,000", () => useReduce(users[1000])); | |
suite.add("reduce() w/ mutate: 10", () => useReduceMutate(users[10])); | |
suite.add("reduce() w/ mutate: 100", () => useReduceMutate(users[100])); | |
suite.add("reduce() w/ mutate: 1,000", () => useReduceMutate(users[1000])); | |
suite.add("forEach(): 10", () => useForEach(users[10])); | |
suite.add("forEach(): 100", () => useForEach(users[100])); | |
suite.add("forEach(): 1,000", () => useForEach(users[1000])); | |
suite.add("filter() & map(): 10", () => useFilterMap(users[10])); | |
suite.add("filter() & map(): 100", () => useFilterMap(users[100])); | |
suite.add("filter() & map(): 1,000", () => useFilterMap(users[1000])); | |
suite.add("filter/map w/ pairs: 10", () => useFilterMap2(users[10])); | |
suite.add("filter/map w/ pairs: 100", () => useFilterMap2(users[100])); | |
suite.add("filter/map w/ pairs: 1,000", () => useFilterMap2(users[1000])); | |
suite.add("fromEntries(): 10", () => useFromEntries(users[10])); | |
suite.add("fromEntries(): 100", () => useFromEntries(users[100])); | |
suite.add("fromEntries(): 1,000", () => useFromEntries(users[1000])); | |
suite.add("transducers: 10", () => useTransduce(users[10])); | |
suite.add("transducers: 100", () => useTransduce(users[100])); | |
suite.add("transducers: 1,000", () => useTransduce(users[1000])); | |
suite.add("for-of-loop: 10", () => useForOfLoop(users[10])); | |
suite.add("for-of-loop: 100", () => useForOfLoop(users[100])); | |
suite.add("for-of-loop: 1,000", () => useForOfLoop(users[1000])); | |
suite.add("for-loop: 10", () => useForLoop(users[10])); | |
suite.add("for-loop: 100", () => useForLoop(users[100])); | |
suite.add("for-loop: 1,000", () => useForLoop(users[1000])); | |
suite.on("complete", () => { | |
suite.forEach(test => console.log(test.toString())); | |
}); | |
suite.run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function useReduce(users) { | |
return users.reduce((acc, curr) => { | |
if (curr.active) return acc; | |
else return { ...acc, [curr.id]: curr.name }; | |
}, {}); | |
} | |
function useReduceMutate(users) { | |
return users.reduce((acc, curr) => { | |
if (curr.active) { | |
return acc; | |
} | |
acc[curr.id] = curr.name; | |
return acc; | |
}, {}); | |
} | |
function useForEach(users) { | |
const result = {}; | |
users.forEach(user => { | |
if (user.active) { | |
return; | |
} | |
result[user.id] = user.name; | |
}); | |
return result; | |
} | |
function useFilterMap(users) { | |
return users | |
.filter(user => !user.active) | |
.map(user => ({ [user.id]: user.name })) | |
.reduce((a, b) => Object.assign(a, b), {}); | |
} | |
function useFilterMap2(users) { | |
return users | |
.filter(user => !user.active) | |
.map(user => [user.id, user.name]) | |
.reduce((a, [id, name]) => Object.assign(a, { [id]: name }), {}); | |
} | |
function useFromEntries(users) { | |
return Object.fromEntries( | |
users.filter(user => !user.active).map(user => [user.id, user.name]) | |
); | |
} | |
function useTransduce(users) { | |
return users.reduce( | |
compose([ | |
filter(user => !user.active), | |
map(user => ({ [user.id]: user.name })) | |
])(assign), | |
{} | |
); | |
} | |
const map = f => step => (a, c) => step(a, f(c)); | |
const filter = pred => step => (a, c) => (pred(c) ? step(a, c) : a); | |
const compose = fns => x => fns.reduceRight((y, f) => f(y), x); | |
const concat = (a, b) => a.concat([b]); | |
const assign = (a, b) => Object.assign(a, b); | |
function useForOfLoop(users) { | |
let result = {}; | |
for (let user of users) { | |
if (!user.active) result[user.id] = user.name; | |
} | |
return result; | |
} | |
function useForLoop(users) { | |
let result = {}; | |
for (let i = 0; i < users.length; i++) { | |
let user = users[i]; | |
if (!user.active) { | |
result[user.id] = user.name; | |
} | |
} | |
return result; | |
} | |
module.exports = { | |
useReduce, | |
useReduceMutate, | |
useForEach, | |
useForLoop, | |
useFilterMap, | |
useFilterMap2, | |
useFromEntries, | |
useTransduce, | |
useForOfLoop | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment