Skip to content

Instantly share code, notes, and snippets.

@jcoglan
Last active May 26, 2021 09:07
Show Gist options
  • Select an option

  • Save jcoglan/138d219eb380b51c52ca0b00da1b86a9 to your computer and use it in GitHub Desktop.

Select an option

Save jcoglan/138d219eb380b51c52ca0b00da1b86a9 to your computer and use it in GitHub Desktop.

benchmark: reduce(), filter(), map(), transducers and for loops

reduce()        10 x 486,918 ops/sec ±1.30% (89 runs sampled)
reduce()       100 x 36,457 ops/sec ±4.33% (81 runs sampled)
reduce()     1,000 x 783 ops/sec ±1.11% (90 runs sampled)

filter() & map()        10 x 116,811 ops/sec ±1.45% (88 runs sampled)
filter() & map()       100 x 9,162 ops/sec ±0.90% (90 runs sampled)
filter() & map()     1,000 x 235 ops/sec ±3.27% (78 runs sampled)
filter() & map()    10,000 x 66.93 ops/sec ±1.61% (68 runs sampled)
filter() & map()   100,000 x 5.45 ops/sec ±16.41% (19 runs sampled)

fromEntries()        10 x 563,396 ops/sec ±1.44% (87 runs sampled)
fromEntries()       100 x 68,920 ops/sec ±2.35% (85 runs sampled)
fromEntries()     1,000 x 7,368 ops/sec ±0.81% (90 runs sampled)
fromEntries()    10,000 x 531 ops/sec ±2.22% (83 runs sampled)
fromEntries()   100,000 x 25.87 ops/sec ±8.24% (45 runs sampled)

transducers        10 x 112,853 ops/sec ±1.75% (88 runs sampled)
transducers       100 x 9,060 ops/sec ±0.79% (88 runs sampled)
transducers     1,000 x 274 ops/sec ±2.89% (80 runs sampled)
transducers    10,000 x 73.55 ops/sec ±7.00% (63 runs sampled)
transducers   100,000 x 7.94 ops/sec ±10.66% (25 runs sampled)

for-loop        10 x 1,931,510 ops/sec ±1.36% (90 runs sampled)
for-loop       100 x 400,292 ops/sec ±1.02% (87 runs sampled)
for-loop     1,000 x 38,818 ops/sec ±10.86% (75 runs sampled)
for-loop    10,000 x 1,429 ops/sec ±1.07% (87 runs sampled)
for-loop   100,000 x 94.78 ops/sec ±3.08% (69 runs sampled)
for-loop 1,000,000 x 5.93 ops/sec ±4.55% (19 runs sampled)
const { Suite } = require('benchmark')
const { useReduce, useFilterMap, useFromEntries, useTransduce, useLoop } = require('./impls')
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, 10000, 100000, 1000000])
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() 10,000', () => useReduce(users[10000]))
// suite.add('reduce() 100,000', () => useReduce(users[100000]))
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() 10,000', () => useFilterMap(users[10000]))
suite.add('filter() & map() 100,000', () => useFilterMap(users[100000]))
suite.add('fromEntries() 10', () => useFromEntries(users[10]))
suite.add('fromEntries() 100', () => useFromEntries(users[100]))
suite.add('fromEntries() 1,000', () => useFromEntries(users[1000]))
suite.add('fromEntries() 10,000', () => useFromEntries(users[10000]))
suite.add('fromEntries() 100,000', () => useFromEntries(users[100000]))
suite.add('transducers 10', () => useTransduce(users[10]))
suite.add('transducers 100', () => useTransduce(users[100]))
suite.add('transducers 1,000', () => useTransduce(users[1000]))
suite.add('transducers 10,000', () => useTransduce(users[10000]))
suite.add('transducers 100,000', () => useTransduce(users[100000]))
suite.add('for-loop 10', () => useLoop(users[10]))
suite.add('for-loop 100', () => useLoop(users[100]))
suite.add('for-loop 1,000', () => useLoop(users[1000]))
suite.add('for-loop 10,000', () => useLoop(users[10000]))
suite.add('for-loop 100,000', () => useLoop(users[100000]))
suite.add('for-loop 1,000,000', () => useLoop(users[1000000]))
suite.on('complete', () => {
suite.forEach((test) => console.log(test.toString()))
})
suite.run()
function useReduce(users) {
return users.reduce((acc, curr) => {
if (curr.active)
return acc
else
return { ...acc, [curr.id]: curr.name }
}, {})
}
function useFilterMap(users) {
return users
.filter(user => !user.active)
.map(user => ({ [user.id]: user.name }))
.reduce((a, b) => Object.assign(a, b), {})
}
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 useLoop(users) {
let results = {}
for (let user of users) {
if (!user.active) results[user.id] = user.name
}
return results
}
module.exports = {
useReduce,
useFilterMap,
useFromEntries,
useTransduce,
useLoop,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment