Last active
April 13, 2022 23:50
-
-
Save kputnam/015f6287dea48471baea9f419bbe274d to your computer and use it in GitHub Desktop.
Object#cons and Object#snoc benchmarks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require "pp" | |
require "benchmark/ips" | |
require "memory_profiler" | |
GC.disable | |
def mem(label, &block) | |
result = MemoryProfiler::Reporter.report(&block) | |
print label.ljust(30); pp result.allocated_memory_by_class | |
end | |
def cons_a(n, xs); i = 0; while i < n; i += 1; [0] + xs ;end;end | |
def cons_b(n, xs); i = 0; while i < n; i += 1; [0, *xs] ;end;end | |
def cons_c(n, xs); i = 0; while i < n; i += 1; [0].push(*xs) ;end;end | |
def cons_d(n, xs); i = 0; while i < n; i += 1; xs.dup.unshift(0) ;end;end | |
def snoc_a(n, xs); i = 0; while i < n; i += 1; xs + [0] ;end;end | |
def snoc_b(n, xs); i = 0; while i < n; i += 1; [*xs, 0] ;end;end | |
def snoc_c(n, xs); i = 0; while i < n; i += 1; xs.dup.push(0) ;end;end | |
def snoc_d(n, xs); i = 0; while i < n; i += 1; [0, *xs.reverse].reverse ;end;end | |
XS = [1, 2, 3, 4].freeze | |
puts "CONS #{"="*73}" | |
mem("[0] + xs") { cons_a(500_000, XS) } | |
mem("[0, *xs]") { cons_b(500_000, XS) } | |
mem("[0].push(*xs)") { cons_c(500_000, XS) } | |
mem("xs.dup.unshift(0)") { cons_d(500_000, XS) } | |
Benchmark.ips do |x| | |
x.report("[0] + xs") {|n| cons_a(n, XS) } | |
x.report("[0, *xs]") {|n| cons_b(n, XS) } | |
x.report("[0].push(*xs)") {|n| cons_c(n, XS) } | |
x.report("xs.dup.unshift(0)") {|n| cons_d(n, XS) } | |
x.compare! | |
end | |
puts "SNOC #{"="*73}" | |
mem("xs + [5]") { snoc_a(500_000, XS) } | |
mem("[*xs, 5]") { snoc_b(500_000, XS) } | |
mem("xs.dup.push(5)") { snoc_c(500_000, XS) } | |
mem("[5, *xs.reverse].reverse") { snoc_d(500_000, XS) } | |
Benchmark.ips do |x| | |
x.report("xs + [5]") {|n| snoc_a(n, XS) } | |
x.report("[*xs, 5]") {|n| snoc_b(n, XS) } | |
x.report("xs.dup.push(5)") {|n| snoc_c(n, XS) } | |
x.report("[5, *xs.reverse].reverse") {|n| snoc_d(n, XS) } | |
x.compare! | |
end | |
mem = Integer(`ps -o rss= -p #{Process.pid}`) * 0.001 | |
puts "Process: %0.2d MiB" % mem |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CONS ========================================================================= | |
[0] + xs [{:data=>"Array", :count=>60000000}] | |
[0, *xs] [{:data=>"Array", :count=>20000000}] | |
[0].push(*xs) [{:data=>"Array", :count=>104000000}] | |
xs.dup.unshift(0) [{:data=>"Array", :count=>104000000}] | |
Warming up -------------------------------------- | |
[0] + xs 158.357k i/100ms | |
[0, *xs] 249.760k i/100ms | |
[0].push(*xs) 144.966k i/100ms | |
xs.dup.unshift(0) 105.764k i/100ms | |
Calculating ------------------------------------- | |
[0] + xs 4.001M (± 6.5%) i/s - 19.953M in 5.012735s | |
[0, *xs] 20.164M (± 3.4%) i/s - 100.903M in 5.010392s | |
[0].push(*xs) 3.402M (± 6.3%) i/s - 17.106M in 5.048869s | |
xs.dup.unshift(0) 1.808M (± 4.0%) i/s - 9.096M in 5.038773s | |
Comparison: | |
[0, *xs]: 20163644.4 i/s | |
[0] + xs: 4000698.8 i/s - 5.04x slower | |
[0].push(*xs): 3401973.3 i/s - 5.93x slower | |
xs.dup.unshift(0): 1808018.4 i/s - 11.15x slower | |
SNOC ========================================================================= | |
xs + [5] [{:data=>"Array", :count=>60000000}] | |
[*xs, 5] [{:data=>"Array", :count=>36000000}] | |
xs.dup.push(5) [{:data=>"Array", :count=>104000000}] | |
[5, *xs.reverse].reverse [{:data=>"Array", :count=>200000000}] | |
Warming up -------------------------------------- | |
xs + [5] 165.681k i/100ms | |
[*xs, 5] 177.168k i/100ms | |
xs.dup.push(5) 107.331k i/100ms | |
[5, *xs.reverse].reverse | |
88.039k i/100ms | |
Calculating ------------------------------------- | |
xs + [5] 3.923M (± 4.0%) i/s - 19.716M in 5.034287s | |
[*xs, 5] 4.486M (± 4.9%) i/s - 22.500M in 5.028227s | |
xs.dup.push(5) 1.803M (± 4.4%) i/s - 9.016M in 5.008696s | |
[5, *xs.reverse].reverse | |
1.250M (±17.9%) i/s - 5.723M in 5.018827s | |
Comparison: | |
[*xs, 5]: 4486418.3 i/s | |
xs + [5]: 3922868.0 i/s - 1.14x slower | |
xs.dup.push(5): 1803477.6 i/s - 2.49x slower | |
[5, *xs.reverse].reverse: 1250223.3 i/s - 3.59x slower | |
Process: 177 MiB |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CONS ========================================================================= | |
[0] + xs [{:data=>"Array", :count=>60000000}] | |
[0, *xs] [{:data=>"Array", :count=>20000000}] | |
[0].push(*xs) [{:data=>"Array", :count=>104000000}] | |
xs.dup.unshift(0) [{:data=>"Array", :count=>104000000}] | |
Warming up -------------------------------------- | |
[0] + xs 167.782k i/100ms | |
[0, *xs] 267.276k i/100ms | |
[0].push(*xs) 154.735k i/100ms | |
xs.dup.unshift(0) 100.309k i/100ms | |
Calculating ------------------------------------- | |
[0] + xs 3.817M (±19.3%) i/s - 18.120M in 5.024482s | |
[0, *xs] 21.515M (± 7.8%) i/s - 106.910M in 5.005655s | |
[0].push(*xs) 3.306M (±14.3%) i/s - 16.092M in 5.004029s | |
xs.dup.unshift(0) 1.687M (± 8.8%) i/s - 8.426M in 5.035796s | |
Comparison: | |
[0, *xs]: 21515378.8 i/s | |
[0] + xs: 3817363.5 i/s - 5.64x slower | |
[0].push(*xs): 3305575.6 i/s - 6.51x slower | |
xs.dup.unshift(0): 1686959.4 i/s - 12.75x slower | |
SNOC ========================================================================= | |
xs + [5] [{:data=>"Array", :count=>60000000}] | |
[*xs, 5] [{:data=>"Array", :count=>36000000}] | |
xs.dup.push(5) [{:data=>"Array", :count=>104000000}] | |
[5, *xs.reverse].reverse [{:data=>"Array", :count=>200000000}] | |
Warming up -------------------------------------- | |
xs + [5] 172.941k i/100ms | |
[*xs, 5] 163.911k i/100ms | |
xs.dup.push(5) 103.533k i/100ms | |
[5, *xs.reverse].reverse | |
92.412k i/100ms | |
Calculating ------------------------------------- | |
xs + [5] 4.185M (± 6.3%) i/s - 20.926M in 5.020849s | |
[*xs, 5] 4.679M (± 6.6%) i/s - 23.275M in 5.000333s | |
xs.dup.push(5) 1.904M (± 4.9%) i/s - 9.525M in 5.015530s | |
[5, *xs.reverse].reverse | |
1.411M (± 4.2%) i/s - 7.116M in 5.051060s | |
Comparison: | |
[*xs, 5]: 4678600.6 i/s | |
xs + [5]: 4184616.8 i/s - same-ish: difference falls within error | |
xs.dup.push(5): 1903741.9 i/s - 2.46x slower | |
[5, *xs.reverse].reverse: 1411382.4 i/s - 3.31x slower | |
Process: 229 MiB |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CONS ========================================================================= | |
[0] + xs [{:data=>"Array", :count=>60000000}] | |
[0, *xs] [{:data=>"Array", :count=>20000000}] | |
[0].push(*xs) [{:data=>"Array", :count=>104000000}] | |
xs.dup.unshift(0) [{:data=>"Array", :count=>104000000}] | |
Warming up -------------------------------------- | |
[0] + xs 182.307k i/100ms | |
[0, *xs] 288.519k i/100ms | |
[0].push(*xs) 147.349k i/100ms | |
xs.dup.unshift(0) 113.528k i/100ms | |
Calculating ------------------------------------- | |
[0] + xs 4.295M (± 8.4%) i/s - 21.512M in 5.031081s | |
[0, *xs] 23.616M (± 6.3%) i/s - 117.716M in 5.005438s | |
[0].push(*xs) 3.833M (±18.4%) i/s - 18.271M in 5.000693s | |
xs.dup.unshift(0) 1.909M (± 5.3%) i/s - 9.536M in 5.009102s | |
Comparison: | |
[0, *xs]: 23616219.6 i/s | |
[0] + xs: 4294929.8 i/s - 5.50x slower | |
[0].push(*xs): 3832976.0 i/s - 6.16x slower | |
xs.dup.unshift(0): 1908544.6 i/s - 12.37x slower | |
SNOC ========================================================================= | |
xs + [5] [{:data=>"Array", :count=>60000000}] | |
[*xs, 5] [{:data=>"Array", :count=>36000000}] | |
xs.dup.push(5) [{:data=>"Array", :count=>104000000}] | |
[5, *xs.reverse].reverse [{:data=>"Array", :count=>200000000}] | |
Warming up -------------------------------------- | |
xs + [5] 191.852k i/100ms | |
[*xs, 5] 205.475k i/100ms | |
xs.dup.push(5) 107.392k i/100ms | |
[5, *xs.reverse].reverse | |
94.345k i/100ms | |
Calculating ------------------------------------- | |
xs + [5] 4.296M (±14.4%) i/s - 21.104M in 5.005134s | |
[*xs, 5] 5.226M (±21.5%) i/s - 25.479M in 5.038493s | |
xs.dup.push(5) 1.976M (±22.4%) i/s - 8.484M in 5.041697s | |
[5, *xs.reverse].reverse | |
1.415M (±19.7%) i/s - 6.887M in 5.020408s | |
Comparison: | |
[*xs, 5]: 5226393.4 i/s | |
xs + [5]: 4295635.6 i/s - same-ish: difference falls within error | |
xs.dup.push(5): 1976485.8 i/s - 2.64x slower | |
[5, *xs.reverse].reverse: 1414967.1 i/s - 3.69x slower | |
Process: 916 MiB |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CONS ========================================================================= | |
[0] + xs [{:data=>"Array", :count=>60000000}] | |
[0, *xs] [] | |
[0].push(*xs) [{:data=>"Array", :count=>104000000}] | |
xs.dup.unshift(0) [{:data=>"Array", :count=>104000000}] | |
Warming up -------------------------------------- | |
[0] + xs 178.548k i/100ms | |
[0, *xs] 313.357k i/100ms | |
[0].push(*xs) 170.827k i/100ms | |
xs.dup.unshift(0) 116.468k i/100ms | |
Calculating ------------------------------------- | |
[0] + xs 4.276M (± 5.1%) i/s - 21.426M in 5.026476s | |
[0, *xs] 45.619M (± 4.3%) i/s - 227.497M in 4.999133s | |
[0].push(*xs) 3.712M (± 7.0%) i/s - 18.620M in 5.045213s | |
xs.dup.unshift(0) 1.946M (± 2.6%) i/s - 9.783M in 5.030577s | |
Comparison: | |
[0, *xs]: 45619256.8 i/s | |
[0] + xs: 4276348.2 i/s - 10.67x slower | |
[0].push(*xs): 3711830.7 i/s - 12.29x slower | |
xs.dup.unshift(0): 1946086.7 i/s - 23.44x slower | |
SNOC ========================================================================= | |
xs + [5] [{:data=>"Array", :count=>60000000}] | |
[*xs, 5] [{:data=>"Array", :count=>36000000}] | |
xs.dup.push(5) [{:data=>"Array", :count=>104000000}] | |
[5, *xs.reverse].reverse [{:data=>"Array", :count=>200000000}] | |
Warming up -------------------------------------- | |
xs + [5] 179.656k i/100ms | |
[*xs, 5] 192.123k i/100ms | |
xs.dup.push(5) 120.012k i/100ms | |
[5, *xs.reverse].reverse | |
99.089k i/100ms | |
Calculating ------------------------------------- | |
xs + [5] 4.240M (± 5.7%) i/s - 21.199M in 5.020647s | |
[*xs, 5] 4.862M (± 5.3%) i/s - 24.400M in 5.035657s | |
xs.dup.push(5) 1.928M (± 4.6%) i/s - 9.721M in 5.052745s | |
[5, *xs.reverse].reverse | |
1.499M (± 3.7%) i/s - 7.531M in 5.032273s | |
Comparison: | |
[*xs, 5]: 4861939.7 i/s | |
xs + [5]: 4239664.7 i/s - 1.15x slower | |
xs.dup.push(5): 1928168.5 i/s - 2.52x slower | |
[5, *xs.reverse].reverse: 1498704.3 i/s - 3.24x slower | |
Process: 352 MiB |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CONS ========================================================================= | |
[0] + xs [{:data=>"Array", :count=>60000000}] | |
[0, *xs] [] | |
[0].push(*xs) [{:data=>"Array", :count=>104000000}] | |
xs.dup.unshift(0) [{:data=>"Array", :count=>104000000}] | |
Warming up -------------------------------------- | |
[0] + xs 299.980k i/100ms | |
[0, *xs] 374.370k i/100ms | |
[0].push(*xs) 290.385k i/100ms | |
xs.dup.unshift(0) 200.042k i/100ms | |
Calculating ------------------------------------- | |
[0] + xs 13.409M (±10.8%) i/s - 66.296M in 5.020000s | |
[0, *xs] 54.612M (± 5.7%) i/s - 271.793M in 4.999686s | |
[0].push(*xs) 12.676M (± 4.8%) i/s - 63.304M in 5.007482s | |
xs.dup.unshift(0) 5.057M (± 2.6%) i/s - 25.405M in 5.027011s | |
Comparison: | |
[0, *xs]: 54611596.6 i/s | |
[0] + xs: 13408678.7 i/s - 4.07x slower | |
[0].push(*xs): 12675808.1 i/s - 4.31x slower | |
xs.dup.unshift(0): 5057342.5 i/s - 10.80x slower | |
SNOC ========================================================================= | |
xs + [5] [{:data=>"Array", :count=>60000000}] | |
[*xs, 5] [{:data=>"Array", :count=>36000000}] | |
xs.dup.push(5) [{:data=>"Array", :count=>104000000}] | |
[5, *xs.reverse].reverse [{:data=>"Array", :count=>200000000}] | |
Warming up -------------------------------------- | |
xs + [5] 242.832k i/100ms | |
[*xs, 5] 332.280k i/100ms | |
xs.dup.push(5) 210.093k i/100ms | |
[5, *xs.reverse].reverse | |
218.821k i/100ms | |
Calculating ------------------------------------- | |
xs + [5] 14.651M (± 2.7%) i/s - 73.335M in 5.010120s | |
[*xs, 5] 21.410M (± 3.2%) i/s - 106.994M in 5.003528s | |
xs.dup.push(5) 5.155M (± 2.4%) i/s - 25.841M in 5.016489s | |
[5, *xs.reverse].reverse | |
5.517M (± 3.2%) i/s - 27.571M in 5.003341s | |
Comparison: | |
[*xs, 5]: 21409550.7 i/s | |
xs + [5]: 14651002.6 i/s - 1.46x slower | |
[5, *xs.reverse].reverse: 5516899.0 i/s - 3.88x slower | |
xs.dup.push(5): 5154712.4 i/s - 4.15x slower | |
Process: 388 MiB |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment