Skip to content

Instantly share code, notes, and snippets.

@gettalong
Created September 15, 2018 07:19
Show Gist options
  • Save gettalong/db63bb3b904bcfe047b8abba8c1ff7c6 to your computer and use it in GitHub Desktop.
Save gettalong/db63bb3b904bcfe047b8abba8c1ff7c6 to your computer and use it in GitHub Desktop.
Transducer vs Ruby vs Lazy Ruby performance
require 'benchmark-driver'
setup_code = <<EOF
require 'ramda'
def transduce(transformation, reducing_fn, initial, input)
input.reduce(initial, &transformation.call(reducing_fn))
end
PUSHES = -> list, item { list.push(item) }
def mapping(&fn)
-> reducing_fn {
-> result, input {
reducing_fn.call(result, fn.call(input))
}
}
end
def selecting(&predicate_fn)
-> reducing_fn {
-> result, input {
if predicate_fn.call(input)
reducing_fn.call(result, input)
else
result
end
}
}
end
transformation = Ramda.compose(
mapping { |x| x + 1 },
selecting { |x| x.even? }
)
a = (0..100_00).to_a
EOF
Benchmark.driver do |bm|
bm.prelude(setup_code)
bm.report('transducer', "transduce(transformation, PUSHES, [], a)")
bm.report('plain Ruby', "a.map {|e| e + 1}.select(&:even?).reduce([], &PUSHES)")
bm.report('lazy Ruby', "a.lazy.map {|e| e + 1}.select(&:even?).reduce([], &PUSHES).to_a")
end
This is the result of running the benchmark:
Warming up --------------------------------------
transducer 195.457 i/s
plain Ruby 651.272 i/s
lazy Ruby 208.310 i/s
Calculating -------------------------------------
transducer 176.151 i/s - 586.000 times in 3.326699s (5.68ms/i)
plain Ruby 654.245 i/s - 1.953k times in 2.985121s (1.53ms/i)
lazy Ruby 230.289 i/s - 624.000 times in 2.709635s (4.34ms/i)
Comparison:
plain Ruby: 654.2 i/s
lazy Ruby: 230.3 i/s - 2.84x slower
transducer: 176.2 i/s - 3.71x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment