Skip to content

Instantly share code, notes, and snippets.

@ChildrenofkoRn
Created September 19, 2021 17:13
Show Gist options
  • Save ChildrenofkoRn/024c8b4ead7447b5282b2a4c211bb148 to your computer and use it in GitHub Desktop.
Save ChildrenofkoRn/024c8b4ead7447b5282b2a4c211bb148 to your computer and use it in GitHub Desktop.
slow Numo::NArray#diff (differences between array elements on Ruby)
require "benchmark/ips"
require 'numo/narray'

Benchmark.ips do |x|
  arr_nums = Array.new(10) { |i| rand(1..100.0) }
  
  x.report "each_cons + map" do
    arr_nums.each_cons(2).map{|a, b| b - a}
  end
  
  x.report "with_index + compact" do
    arr_nums.map.with_index(1){|e,i| arr_nums[i]-e if arr_nums[i] }.compact
  end
  
  x.report "Numo::NArray#diff" do
    Numo::DFloat[*arr_nums].diff
  end
  
  x.compare!
end
Warming up --------------------------------------
     each_cons + map    45.734k i/100ms
with_index + compact    53.343k i/100ms
   Numo::NArray#diff     6.803k i/100ms
Calculating -------------------------------------
     each_cons + map    464.805k (± 6.3%) i/s -      2.332M in   5.045992s
with_index + compact    536.279k (± 1.9%) i/s -      2.720M in   5.074751s
   Numo::NArray#diff     67.043k (± 2.1%) i/s -    340.150k in   5.075870s

Comparison:
with_index + compact:   536279.1 i/s
     each_cons + map:   464805.1 i/s - 1.15x  (± 0.00) slower
   Numo::NArray#diff:    67043.3 i/s - 8.00x  (± 0.00) slower

Interestingly, numpy.diff also seems to have performance problems.

@ChildrenofkoRn
Copy link
Author

As it turns out, Numo becomes faster on large arrays:

require "benchmark/ips"
require 'numo/narray'

Benchmark.ips do |x|

  arr_nums = Array.new(10_000) {|i| rand(1..100.0) }

  x.report "each_cons + map" do
    arr_nums.each_cons(2).map{|a, b| b - a}
  end

  x.report "with_index + compact" do
    arr_nums.map.with_index(1){|e,i| arr_nums[i]-e if arr_nums[i] }.compact
  end

  # its more correct to use .cast to convert to a Numo::NArray object
  x.report "Numo::NArray#diff" do
    Numo::DFloat.cast(arr_nums).diff
  end

  x.compare!
end
Warming up --------------------------------------
     each_cons + map    82.000  i/100ms
with_index + compact    83.000  i/100ms
   Numo::NArray#diff   118.000  i/100ms
Calculating -------------------------------------
     each_cons + map    815.180  (± 3.7%) i/s -      4.100k in   5.037040s
with_index + compact    842.955  (± 5.2%) i/s -      4.233k in   5.039982s
   Numo::NArray#diff      1.235k (± 3.9%) i/s -      6.254k in   5.074269s

Comparison:
   Numo::NArray#diff:     1234.7 i/s
with_index + compact:      843.0 i/s - 1.46x  (± 0.00) slower
     each_cons + map:      815.2 i/s - 1.51x  (± 0.00) slower

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment