👑SP↠

Transducer and latest nodejs (>= 10) can sing faster duet

October 19, 2019

transducer-perf

Prerequisite

Need some basic understanding of

I will also link more interesting articles about functional programming and transducers in the end.

Excercise

Now run the following code-which is in nutshell, just filter registered users and sum up the total discount from the given millions of users(array) in 3 different ways-against nodejs versions 8, 9, 10, 12

const { map, filter, compose, transduce } = require('ramda');

// utils
const timeIt = (label, fn) => {
  console.time(label);
  fn();
  console.timeEnd(label);
};

const getRange = n => [...Array(n).keys()]

// data
const users = getRange(1000000).map((_, index) => ({
  registered: index % 2 === 0,
  discount: 1,
}))

// helpers
const isRegistered = user => user.registered;
const getDiscount = user => user.discount;
const totalDiscountReducer = (
  totalDiscount,
  discount
) => totalDiscount + discount;

// efficient way to get total discount
const getTotalDiscountForRegisteredUsersEfficiently = () => {
  let totalDiscount = 0;
  users.forEach(user => {
    if(user.registered) totalDiscount += user.discount;
  })
  return totalDiscount;
}

// elegant way to get total discount
const getTotalDiscountForRegisteredUsersElegantly = () => users
  .filter(isRegistered)
  .map(getDiscount)
  .reduce(totalDiscountReducer, 0)

const getDiscountForRegisteredUser = compose(
  filter(isRegistered),
  map(getDiscount)
);
// elegant and efficient way to get total discount
const getTotalDiscountForRegisteredUsers = () => transduce(
  getDiscountForRegisteredUser,
  totalDiscountReducer,
  0,
  users
)

timeIt(
  'Loop(Efficient)',
  getTotalDiscountForRegisteredUsersEfficiently
)
timeIt(
  'Chaining(Elegant)',
  getTotalDiscountForRegisteredUsersElegantly
)
timeIt(
  'Transduce(Efficient and Elegant)',
  getTotalDiscountForRegisteredUsers
)

I have prepared runkit link too: https://runkit.com/peramanathan/transducer-simplified

Match your results

  • Node 8:
"Loop(Efficient): 25.328ms"
"Chaining(Elegant): 247.965ms"
"Transduce(Efficient and Elegant): 631.458ms"
  • Node 9:
"Loop(Efficient): 21.147ms"
"Chaining(Elegant): 154.018ms"
"Transduce(Efficient and Elegant): 688.818ms"
  • Node 10:
"Loop(Efficient): 17.144ms"
"Chaining(Elegant): 106.336ms"
"Transduce(Efficient and Elegant): 14.785ms"
  • Node 11
"Loop(Efficient): 21.290ms"
"Chaining(Elegant): 152.711ms"
"Transduce(Efficient and Elegant): 16.327ms"
  • Node 12
"Loop(Efficient): 34.232ms"
"Chaining(Elegant): 102.873ms"
"Transduce(Efficient and Elegant): 11.597ms"

Read more


Written by Peramanathan Sathyamoorthy who lives and works in Stockholm, Sweden. follow me on Twitter

© 2023 Peramanathan Sathyamoorthy