Skip to content

Instantly share code, notes, and snippets.

@ivopt
Last active October 31, 2017 17:21
Show Gist options
  • Save ivopt/50018af8675334bbdada33e04600a1aa to your computer and use it in GitHub Desktop.
Save ivopt/50018af8675334bbdada33e04600a1aa to your computer and use it in GitHub Desktop.
Merging vs Adding and Sorting 2 pre-sorted collections
require 'benchmark'
# ------------------------------------------------------------------------------
# Add 2 collections together and sort the result
def add_and_sort(left, right)
(left + right).sort { |a, b| b[:updated_at] <=> a[:updated_at] }
end
# ------------------------------------------------------------------------------
# Merge 2 previously ordered collections together
def merge(left, right)
result = []
remainder = loop do
(result << left.shift) until lesser(left, right)
break right if left.empty?
(result << right.shift) until lesser(right, left)
break left if right.empty?
end
result + remainder
end
def lesser(one, other)
one.empty? ||
other.empty? ||
one.first[:updated_at] < other.first[:updated_at]
end
# ------------------------------------------------------------------------------
# SETUP
def build_arrays(size)
now = Time.now
a = Array.new(size) { |i| { updated_at: now - i*2 } }
b = Array.new(size) { |i| { updated_at: now - (i*2+1) } }
return [a,b]
end
def test(times, method)
a,b = build_arrays(times)
send(method, a, b)
end
# ------------------------------------------------------------------------------
# Running tests...
Benchmark.bmbm(15) do |x|
x.report('merge 10x') { test(10, :merge) }
x.report('a+s 10x') { test(10, :add_and_sort) }
x.report('merge 1000x') { test(1000, :merge) }
x.report('a+s 1000x') { test(1000, :add_and_sort) }
x.report('merge 100000x') { test(100000, :merge) }
x.report('a+s 100000x') { test(100000, :add_and_sort) }
x.report('merge 1000000x') { test(1000000, :merge) }
x.report('a+s 1000000x') { test(1000000, :add_and_sort) }
end
Rehearsal ---------------------------------------------------
merge 10x 0.000000 0.000000 0.000000 ( 0.000033)
a+s 10x 0.000000 0.000000 0.000000 ( 0.000187)
merge 1000x 0.000000 0.000000 0.000000 ( 0.002411)
a+s 1000x 0.010000 0.000000 0.010000 ( 0.004957)
merge 100000x 0.230000 0.020000 0.250000 ( 0.255833)
a+s 100000x 0.780000 0.020000 0.800000 ( 0.791663)
merge 1000000x 3.540000 0.200000 3.740000 ( 3.743085)
a+s 1000000x 10.030000 0.400000 10.430000 ( 10.437322)
----------------------------------------- total: 15.230000sec
user system total real
merge 10x 0.000000 0.000000 0.000000 ( 0.000043)
a+s 10x 0.000000 0.000000 0.000000 ( 0.000049)
merge 1000x 0.000000 0.000000 0.000000 ( 0.002536)
a+s 1000x 0.010000 0.000000 0.010000 ( 0.004930)
merge 100000x 0.220000 0.010000 0.230000 ( 0.235227)
a+s 100000x 0.700000 0.050000 0.750000 ( 0.759551)
merge 1000000x 3.240000 0.650000 3.890000 ( 3.899715)
a+s 1000000x 9.380000 1.170000 10.550000 ( 10.554972)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment