Skip to content

Instantly share code, notes, and snippets.

@goldeneggg
Last active June 28, 2020 06:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goldeneggg/e363f96195cbaa14b64ede2151f503c7 to your computer and use it in GitHub Desktop.
Save goldeneggg/e363f96195cbaa14b64ede2151f503c7 to your computer and use it in GitHub Desktop.
[ruby] 一覧から重複削除してnilを除去、の実装方法別パフォーマンス比較
require 'benchmark/ips'
require 'benchmark/memory'
require 'set'
CLASSES = [
Class.new {
@arr = ['1', '2', '33', '444', nil, '5555', nil, '444', '66666', 'abcde', '777777', nil, 'XXXX', '33', 'zzzzzzzzzz']
def self.label
'Set->reject'
end
def self.exec
Set.new(@arr).reject{|a| a.nil? }
end
},
Class.new {
@arr = ['1', '2', '33', '444', nil, '5555', nil, '444', '66666', 'abcde', '777777', nil, 'XXXX', '33', 'zzzzzzzzzz']
def self.label
'Set->reject!'
end
def self.exec
Set.new(@arr).reject!{|a| a.nil? }
end
},
Class.new {
@arr = ['1', '2', '33', '444', nil, '5555', nil, '444', '66666', 'abcde', '777777', nil, 'XXXX', '33', 'zzzzzzzzzz']
def self.label
'uniq->reject'
end
def self.exec
@arr.uniq.reject{|a| a.nil? }
end
},
Class.new {
@arr = ['1', '2', '33', '444', nil, '5555', nil, '444', '66666', 'abcde', '777777', nil, 'XXXX', '33', 'zzzzzzzzzz']
def self.label
'uniq->reject!'
end
def self.exec
@arr.uniq.reject!{|a| a.nil? }
end
},
]
def ips
Benchmark.ips do |x|
x.time = 15
x.warmup = 5
CLASSES.each do |c|
x.report(c.label) { c.exec }
end
x.compare!
end
end
def memory
Benchmark.memory do |x|
CLASSES.each do |c|
x.report(c.label) { c.exec }
end
x.compare!
end
end
ips
memory
@goldeneggg
Copy link
Author

% ruby bench_uniq_reject.rb

Warming up --------------------------------------
         Set->reject    11.897k i/100ms
        Set->reject!    10.975k i/100ms
        uniq->reject    21.109k i/100ms
       uniq->reject!    22.171k i/100ms
Calculating -------------------------------------
         Set->reject    120.510k (± 4.1%) i/s -      1.808M in  15.034661s
        Set->reject!    112.692k (± 3.0%) i/s -      1.690M in  15.013187s
        uniq->reject    220.198k (± 3.4%) i/s -      3.314M in  15.069115s
       uniq->reject!    236.016k (± 2.7%) i/s -      3.547M in  15.042487s

Comparison:
       uniq->reject!:   236016.0 i/s
        uniq->reject:   220197.8 i/s - 1.07x  slower
         Set->reject:   120509.8 i/s - 1.96x  slower
        Set->reject!:   112692.4 i/s - 2.09x  slower

Calculating -------------------------------------
         Set->reject     1.952k memsize (     0.000  retained)
                        19.000  objects (     0.000  retained)
                        10.000  strings (     0.000  retained)
        Set->reject!     1.936k memsize (     0.000  retained)
                        21.000  objects (     0.000  retained)
                        10.000  strings (     0.000  retained)
        uniq->reject   728.000  memsize (     0.000  retained)
                        12.000  objects (     0.000  retained)
                        10.000  strings (     0.000  retained)
       uniq->reject!   528.000  memsize (     0.000  retained)
                        11.000  objects (     0.000  retained)
                        10.000  strings (     0.000  retained)

Comparison:
       uniq->reject!:        528 allocated
        uniq->reject:        728 allocated - 1.38x more
        Set->reject!:       1936 allocated - 3.67x more
         Set->reject:       1952 allocated - 3.70x more

@goldeneggg
Copy link
Author

goldeneggg commented Dec 12, 2018

.reject{|a| a.nil? } の代わりに compact を、.reject!{|a| a.nil? } の代わりに compact! を使った場合も比較対象に追加して計測

compact!, compact が速い

% ruby bench_uniq_reject.rb

Warming up --------------------------------------
     Set->reject nil    12.032k i/100ms
    Set->reject! nil    11.094k i/100ms
    uniq->reject nil    20.897k i/100ms
   uniq->reject! nil    21.951k i/100ms
       uniq->compact    24.669k i/100ms
      uniq->compact!    25.309k i/100ms
Calculating -------------------------------------
     Set->reject nil    115.901k (± 7.7%) i/s -      1.733M in  15.047491s
    Set->reject! nil    107.887k (± 8.4%) i/s -      1.609M in  15.034735s
    uniq->reject nil    220.234k (± 4.3%) i/s -      3.302M in  15.024091s
   uniq->reject! nil    234.395k (± 3.5%) i/s -      3.512M in  15.003571s
       uniq->compact    261.002k (± 3.8%) i/s -      3.922M in  15.052946s
      uniq->compact!    276.562k (± 3.4%) i/s -      4.151M in  15.027452s

Comparison:
      uniq->compact!:   276561.9 i/s
       uniq->compact:   261001.6 i/s - same-ish: difference falls within error
   uniq->reject! nil:   234394.6 i/s - 1.18x  slower
    uniq->reject nil:   220234.3 i/s - 1.26x  slower
     Set->reject nil:   115900.6 i/s - 2.39x  slower
    Set->reject! nil:   107886.9 i/s - 2.56x  slower

Calculating -------------------------------------
     Set->reject nil     1.952k memsize (     0.000  retained)
                        19.000  objects (     0.000  retained)
                        10.000  strings (     0.000  retained)
    Set->reject! nil     1.936k memsize (     0.000  retained)
                        21.000  objects (     0.000  retained)
                        10.000  strings (     0.000  retained)
    uniq->reject nil   728.000  memsize (     0.000  retained)
                        12.000  objects (     0.000  retained)
                        10.000  strings (     0.000  retained)
   uniq->reject! nil   528.000  memsize (     0.000  retained)
                        11.000  objects (     0.000  retained)
                        10.000  strings (     0.000  retained)
       uniq->compact   656.000  memsize (     0.000  retained)
                        12.000  objects (     0.000  retained)
                        10.000  strings (     0.000  retained)
      uniq->compact!   528.000  memsize (     0.000  retained)
                        11.000  objects (     0.000  retained)
                        10.000  strings (     0.000  retained)

Comparison:
   uniq->reject! nil:        528 allocated
      uniq->compact!:        528 allocated - same
       uniq->compact:        656 allocated - 1.24x more
    uniq->reject nil:        728 allocated - 1.38x more
    Set->reject! nil:       1936 allocated - 3.67x more
     Set->reject nil:       1952 allocated - 3.70x more

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