Faster counting in ruby 2
Assuming you want to do something 100.000 times.
The usual way is, to run a loop and use an counter
i =0 while i < 100000 do #DO something i = i+1 # in some languages you have i++ instead end
this sets i to it’s former value plus one after every loop.
I did a benchmark between Integer#+1 and Integer#next
Integer next is the favourite, because it knows, that it needs to count plus one already.
Here is the result:
jrw@sublime:~$ ruby integer_next_against_plus_1.rb using i.next 100 times 1 101 0.000000 0.000000 0.000000 ( 0.000115) using i+1 100 times 1 101 0.000000 0.000000 0.000000 ( 0.000108) using i.next 1000 times 101 1101 0.000000 0.000000 0.000000 ( 0.000881) using i+1 1000 times 101 1101 0.000000 0.000000 0.000000 ( 0.001130) using i.next 10000 times 1101 11101 0.020000 0.000000 0.020000 ( 0.011330) using i+1 10000 times 1101 11101 0.000000 0.000000 0.000000 ( 0.011211) using i.next 100000 times 11101 111101 0.080000 0.020000 0.100000 ( 0.118224) using i+1 100000 times 11101 111101 0.080000 0.010000 0.090000 ( 0.110932) using i.next 1000000 times 111101 1111101 0.690000 0.230000 0.920000 ( 0.998541) using i+1 1000000 times 111101 1111101 0.800000 0.180000 0.980000 ( 1.051063) using i.next 10000000 times 1111101 11111101 7.000000 2.060000 9.060000 ( 9.769309) using i+1 10000000 times 1111101 11111101 7.630000 2.110000 9.740000 ( 10.480469) using i.next 100000000 times 11111101 111111101 68.130000 19.560000 87.690000 ( 89.887507) using i+1 100000000 times 11111101 111111101 76.420000 19.240000 95.660000 ( 98.498498) using i.next 1000000000 times 111111101
and here the code
require 'benchmark'
i1 = 1
i2 = 1
r1 = ""
r2 = ""
time = 100
while time < 100000000000000
puts "using i.next #{time} times"
puts i1
r1 = Benchmark.measure do
time.times do
i1 = i1.next
end
end
puts i1
puts r1
puts "using i+1 #{time} times"
puts i2
r2 = Benchmark.measure do
time.times do
i2 = i2+1
end
end
puts i2
puts r2
time = time * 10
end
So, if you want to count, it’s alsmost 10% faster, to use builtin Integer.next
Trackbacks
Verwenden Sie den folgenden Link zur Rückverlinkung von Ihrer eigenen Seite:
http://praktikanten.brueckenschlaeger.org/trackbacks?article_id=298
I think more considerable than the speed of incrementing number is the performance of different kinds of loops. I’d like to see measurements of:
Ranges w/ each: (0..10000).each {|i|}
Integer#upto: 0.upto(10000) {|i|}
Integer#times: 10000.times {|i|}
Enumerable#each_with_index (even though not applicable in this range of examples, this is probably the most widely used application of counting in our apps)
All these are implemented in C, hence benefit from the optimization of incrementing done by the compiler.
Anyway, nice work, thank you very much. (maybe I’ll do those benchmarks I suggested at some point myself…)
Uh, one last thing: You can write numbers much readable by using underscores: 100000 == 100_000
yes.
i also did comparison of finding very long integers in a list against very short integers.
I did it in a discussion, whether GUI (globally unique identifiers) are a good thing or not.
The result was: Kind of equal, but of course slower. I will post this.