Skip to content

Instantly share code, notes, and snippets.

@ChrisLundquist
Last active December 9, 2015 23:31
Show Gist options
  • Save ChrisLundquist/d06b6cdf1c208d2e7f18 to your computer and use it in GitHub Desktop.
Save ChrisLundquist/d06b6cdf1c208d2e7f18 to your computer and use it in GitHub Desktop.
$ ruby -v
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin14]
Rehearsal --------------------------------------------------------------
map_compact 0.020000 0.000000 0.020000 ( 0.015315)
map_inplace_compact 0.010000 0.000000 0.010000 ( 0.016069)
reject_map 0.010000 0.000000 0.010000 ( 0.014038)
reject_inplace_map 0.860000 0.010000 0.870000 ( 0.860999)
reject_map_inplace 0.010000 0.000000 0.010000 ( 0.013710)
reject_inplace_map_inplace 0.860000 0.000000 0.860000 ( 0.866945)
----------------------------------------------------- total: 1.780000sec
user system total real
map_compact 0.010000 0.000000 0.010000 ( 0.012554)
map_inplace_compact 0.010000 0.000000 0.010000 ( 0.012114)
reject_map 0.010000 0.000000 0.010000 ( 0.021661)
reject_inplace_map 0.850000 0.000000 0.850000 ( 0.855091)
reject_map_inplace 0.010000 0.000000 0.010000 ( 0.015349)
reject_inplace_map_inplace 0.870000 0.000000 0.870000 ( 0.876531)
#!/usr/bin/env ruby
require 'benchmark'
def data
(0...100_000).to_a
end
def map_compact
data.map do |i|
next if i.odd?
i + i
end.compact
end
def map_inplace_compact
data.map! do |i|
next if i.odd?
i + i
end.compact
end
def reject_map
data.reject { |i| i.odd? }.map { |i| i + i }
end
def reject_inplace_map
data.reject! { |i| i.odd? }.map { |i| i + i }
end
def reject_inplace_map_inplace
data.reject! { |i| i.odd? }.map! { |i| i + i }
end
def reject_map_inplace
data.reject { |i| i.odd? }.map! { |i| i + i }
end
Benchmark.bmbm do |x|
x.report("map_compact") { map_compact }
x.report("map_inplace_compact") { map_inplace_compact }
x.report("reject_map") { reject_map }
x.report("reject_inplace_map") { reject_inplace_map }
x.report("reject_map_inplace") { reject_map_inplace }
x.report("reject_inplace_map_inplace") { reject_inplace_map_inplace }
end
@ChrisLundquist
Copy link
Author

Using ruby-prof and 1_000_000 elements it took 262 seconds to run.
Using only 1_000_000 elements and no profiler took 131s.
100_000 elements took about 5.5 seconds

$ ruby tenderlove.rb 
Calculating -------------------------------------
reject_inplace_map_inplace
                    x     1.000  i/100ms
-------------------------------------------------
reject_inplace_map_inplace
                          0.008  (± 0.0%) i/s -      1.000  in 131.980742s
Measure Mode: wall_time
Thread ID: 70302340168920
Fiber ID: 70302352779980
Total: 262.674414
Sort by: self_time

 %self      total      self      wait     child     calls  name
 99.58    262.426   261.581     0.000     0.846        2   Array#reject!
  0.32      0.846     0.846     0.000     0.000  2000000   Fixnum#odd?
  0.06      0.167     0.167     0.000     0.000        2   Array#map!
  0.03      0.077     0.077     0.000     0.000        2   Range#each
  0.00      0.003     0.003     0.000     0.000        2   <Module::GC>#start
  0.00    262.674     0.000     0.000   262.674        1   Global#[No method]
  0.00      0.000     0.000     0.000     0.000        9   IO#write
  0.00    262.674     0.000     0.000   262.674        6  *Array#each
  0.00      0.000     0.000     0.000     0.000        5   String#%
  0.00    262.674     0.000     0.000   262.674        1   Benchmark::IPS#ips
  0.00      0.000     0.000     0.000     0.000       11   <Class::Time>#now
  0.00      0.000     0.000     0.000     0.000        5   Rational#/
  0.00      0.000     0.000     0.000     0.000        4   Time#to_f
  0.00      0.000     0.000     0.000     0.000        4   Float#to_i
  0.00      0.000     0.000     0.000     0.000       11   Time#initialize
  0.00      0.000     0.000     0.000     0.000        3   Benchmark::IPS::Helpers#scale
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Report::Entry#body
  0.00      0.000     0.000     0.000     0.000       11   <Class::Time>#allocate
  0.00      0.077     0.000     0.000     0.077        2   Enumerable#to_a
  0.00      0.000     0.000     0.000     0.000        1   Time#-
  0.00      0.000     0.000     0.000     0.000        2   Benchmark::IPS::Job::Entry#label_rjust
  0.00    131.983     0.000     0.000   131.983        1   Benchmark::IPS::Job#run
  0.00      0.000     0.000     0.000     0.000        2   Benchmark::IPS::Job#time_us
  0.00      0.000     0.000     0.000     0.000        3   <Module::Math>#log10
  0.00    262.670     0.000     0.000   262.670        2   Object#reject_inplace_map_inplace
  0.00    262.671     0.000     0.000   262.670        2   Benchmark::IPS::Job::Entry#call_times
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Job#initialize
  0.00      0.000     0.000     0.000     0.000        5   Numeric#quo
  0.00      0.000     0.000     0.000     0.000        1   Float#**
  0.00      0.000     0.000     0.000     0.000       17   Fixnum#+
  0.00      0.000     0.000     0.000     0.000        4  *Class#new
  0.00      0.000     0.000     0.000     0.000        4   Time#<=>
  0.00      0.003     0.000     0.000     0.003        2   <Module::Benchmark::Timing>#clean_env
  0.00      0.000     0.000     0.000     0.000        3   Float#*
  0.00      0.000     0.000     0.000     0.000        5   Rational#to_f
  0.00      0.000     0.000     0.000     0.000        2   <Module::Benchmark::Timing>#mean
  0.00      0.000     0.000     0.000     0.000        4   Enumerable#inject
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Job::Entry#initialize
  0.00      0.000     0.000     0.000     0.000        3   Kernel#hash
  0.00      0.000     0.000     0.000     0.000        4   Comparable#<
  0.00      0.000     0.000     0.000     0.000        2   <Module::Benchmark::IPS>#options
  0.00    262.670     0.000     0.000   262.670        2   Proc#call
  0.00      0.000     0.000     0.000     0.000        7   Fixnum#to_f
  0.00      0.077     0.000     0.000     0.077        2   Object#data
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Job#iterations_per_sec
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Report::Entry#initialize
  0.00      0.000     0.000     0.000     0.000        4   Kernel#respond_to?
  0.00      0.000     0.000     0.000     0.000        3   IO#puts
  0.00      0.000     0.000     0.000     0.000        1   Hash#[]=
  0.00      0.000     0.000     0.000     0.000        5   Fixnum#fdiv
  0.00      0.000     0.000     0.000     0.000        1   Array#map
  0.00      0.000     0.000     0.000     0.000        2   Time#+
  0.00      0.000     0.000     0.000     0.000        1   IO#printf
  0.00      0.000     0.000     0.000     0.000        4   <Class::BasicObject>#allocate
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Job#create_report
  0.00      0.000     0.000     0.000     0.000        4   Float#to_f
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Report#add_entry
  0.00      0.000     0.000     0.000     0.000        3   Fixnum#**
  0.00      0.000     0.000     0.000     0.000        2   IO#print
  0.00      0.000     0.000     0.000     0.000        1   Float#<=
  0.00      0.000     0.000     0.000     0.000        1   IO#sync
  0.00      0.000     0.000     0.000     0.000        1   Float#round
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Job#cycles_per_100ms
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Job#json?
  0.00      0.000     0.000     0.000     0.000        9   Float#/
  0.00      0.000     0.000     0.000     0.000        4   Fixnum#<=>
  0.00      0.000     0.000     0.000     0.000        1   <Module::Benchmark::Timing>#stddev
  0.00      0.000     0.000     0.000     0.000        2   String#to_s
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Job#config
  0.00      0.000     0.000     0.000     0.000        2   String#*
  0.00      0.000     0.000     0.000     0.000        1   <Module::Math>#sqrt
  0.00      0.000     0.000     0.000     0.000        1   Float#abs
  0.00      0.000     0.000     0.000     0.000        1   Float#>=
  0.00    130.692     0.000     0.000   130.692        1   Benchmark::IPS::Job#run_warmup
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Report::Entry#show_total_time!
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Job#item
  0.00      0.000     0.000     0.000     0.000        2   IO#sync=
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Job#compare?
  0.00      0.000     0.000     0.000     0.000        1   String#ljust
  0.00      0.000     0.000     0.000     0.000        2   NilClass#nil?
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Report::Entry#stddev_percentage
  0.00      0.000     0.000     0.000     0.000        2   Kernel#respond_to_missing?
  0.00      0.000     0.000     0.000     0.000        1   Fixnum#-
  0.00      0.000     0.000     0.000     0.000        1   Proc#arity
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Report#initialize
  0.00      0.000     0.000     0.000     0.000        1   Fixnum#*
  0.00      0.000     0.000     0.000     0.000        1   Kernel#kind_of?
  0.00      0.000     0.000     0.000     0.000        1   Benchmark::IPS::Report::Entry#seconds
  0.00      0.000     0.000     0.000     0.000        1   Array#push
  0.00      0.000     0.000     0.000     0.000        1   Fixnum#/
  0.00      0.000     0.000     0.000     0.000        1   Kernel#is_a?
  0.00      0.000     0.000     0.000     0.000        1   Array#last
  0.00      0.000     0.000     0.000     0.000        1   <Module::Benchmark::Timing>#variance

@ChrisLundquist
Copy link
Author

screen shot 2015-12-04 at 7 30 14 pm

require  "time"

def data(size)
  (0...size).to_a
end

def reject_inplace(size)
  filtered = data(size)
  filtered = filtered.reject! { |i| i.odd? }
  filtered
end

def graph
  40.times.reduce({}) do |acc,i|
    size = ( i + 1) * 10000
    start = Time.now
    reject_inplace(size)
    finish = Time.now
    duration = finish - start
    acc[size] = duration
    acc
  end
end

data = graph
data.keys.sort.each do |k| puts("#{ k },#{data[k]}") end

That's a pretty good N^2 curve fit.
Today I learned not to use reject! until ruby > 2.2.3

@ChrisLundquist
Copy link
Author

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