-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Open
Description
Creating an Array just to use Enumerable#max or Enumerable#min leads to significant performance overhead.
This issue does not exist on Ruby.
crystal version
Crystal 1.16.0 [53cead6be] (2025-04-09)
LLVM: 18.1.8
Default target: x86_64-unknown-linux-gnu
cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=24.04
DISTRIB_CODENAME=noble
DISTRIB_DESCRIPTION="Ubuntu 24.04.2 LTS"
Crystal
cat main.cr
require "benchmark"
def operator(numbers : Array(Array(Int32)))
numbers.map { |a| a[0] > a[1] ? a[0] : a[1] }
end
def enumerable_max(numbers : Array(Array(Int32)))
numbers.map { |a| [a[0], a[1]].max }
end
random_numbers = Array.new(100_000) { [rand(1..100), rand(1..100)] }
Benchmark.ips do |x|
x.report("Operator") { operator(random_numbers) }
x.report("Enumerable#max") { enumerable_max(random_numbers) }
endcrystal build --release main.cr && ./main
Operator 5.33k (187.69µs) (± 2.49%) 391kB/op fastest
Enumerable#max 372.85 ( 2.68ms) (± 1.06%) 4.96MB/op 14.29× slower
Ruby
cat main.rb
require "benchmark/ips"
def operator(numbers)
numbers.map { |a| a[0] > a[1] ? a[0] : a[1] }
end
def enumerable_max(numbers)
numbers.map { |a| [a[0], a[1]].max }
end
random_numbers = Array.new(100_000) { [rand(1..100), rand(1..100)] }
Benchmark.ips do |x|
x.report("Operator") { operator(random_numbers) }
x.report("Enumerable#max") { enumerable_max(random_numbers) }
endruby main.rb
ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [x86_64-linux]
Warming up --------------------------------------
Operator 24.000 i/100ms
Enumerable#max 25.000 i/100ms
Calculating -------------------------------------
Operator 246.669 (± 2.0%) i/s (4.05 ms/i) - 1.248k in 5.061202s
Enumerable#max 259.661 (± 1.5%) i/s (3.85 ms/i) - 1.300k in 5.007469s
Reactions are currently unavailable