Skip to content

Instantly share code, notes, and snippets.

@jcoglan

jcoglan/README.md

Last active May 26, 2021
Embed
What would you like to do?

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

reduce()        10            x 574,156 ops/sec ±1.34% (86 runs sampled)
reduce()       100            x 42,746 ops/sec ±1.99% (88 runs sampled)
reduce()     1,000            x 781 ops/sec ±1.61% (88 runs sampled)

filter() & map()        10    x 128,652 ops/sec ±1.21% (87 runs sampled)
filter() & map()       100    x 9,537 ops/sec ±1.22% (90 runs sampled)
filter() & map()     1,000    x 256 ops/sec ±1.07% (81 runs sampled)
filter() & map()    10,000    x 67.54 ops/sec ±2.56% (68 runs sampled)
filter() & map()   100,000    x 5.63 ops/sec ±16.64% (20 runs sampled)

filter/map w/ pairs        10 x 115,949 ops/sec ±1.52% (87 runs sampled)
filter/map w/ pairs       100 x 8,870 ops/sec ±1.86% (88 runs sampled)
filter/map w/ pairs     1,000 x 277 ops/sec ±1.34% (81 runs sampled)
filter/map w/ pairs    10,000 x 71.10 ops/sec ±1.37% (61 runs sampled)
filter/map w/ pairs   100,000 x 6.68 ops/sec ±3.38% (20 runs sampled)

fromEntries()        10       x 567,847 ops/sec ±1.71% (84 runs sampled)
fromEntries()       100       x 70,766 ops/sec ±1.71% (85 runs sampled)
fromEntries()     1,000       x 7,447 ops/sec ±0.93% (90 runs sampled)
fromEntries()    10,000       x 548 ops/sec ±1.66% (85 runs sampled)
fromEntries()   100,000       x 26.91 ops/sec ±13.13% (47 runs sampled)

transducers        10         x 108,782 ops/sec ±1.93% (84 runs sampled)
transducers       100         x 8,825 ops/sec ±1.41% (88 runs sampled)
transducers     1,000         x 272 ops/sec ±2.02% (80 runs sampled)
transducers    10,000         x 74.95 ops/sec ±0.99% (64 runs sampled)
transducers   100,000         x 7.60 ops/sec ±6.52% (24 runs sampled)

for-loop        10            x 1,880,249 ops/sec ±1.33% (89 runs sampled)
for-loop       100            x 394,682 ops/sec ±1.32% (89 runs sampled)
for-loop     1,000            x 45,280 ops/sec ±1.45% (86 runs sampled)
for-loop    10,000            x 1,439 ops/sec ±0.92% (88 runs sampled)
for-loop   100,000            x 97.50 ops/sec ±1.69% (71 runs sampled)
for-loop 1,000,000            x 6.03 ops/sec ±4.85% (19 runs sampled)
const { Suite } = require('benchmark')
const { useReduce, useFilterMap, useFilterMap2, 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('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('filter/map w/ pairs 10,000', () => useFilterMap2(users[10000]))
suite.add('filter/map w/ pairs 100,000', () => useFilterMap2(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 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 useLoop(users) {
let results = {}
for (let user of users) {
if (!user.active) results[user.id] = user.name
}
return results
}
module.exports = {
useReduce,
useFilterMap,
useFilterMap2,
useFromEntries,
useTransduce,
useLoop,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment