require 'benchmark'
class Float
def round_to(x)
(self * 10**x).round.to_f / 10**x
end
def ceil_to(x)
(self * 10**x).ceil.to_f / 10**x
end
def floor_to(x)
(self * 10**x).floor.to_f / 10**x
end
def round_to_sprintf_f(x)
("%.#{x}f" % x).to_f
end
def round_to_sprintf_sprintf(x)
sprintf("%.#{x}f", x)
end
def round_to_sprintf_modulus(x)
"%.#{x}f" % x
end
end
num = 34.2342134
place = 3
TIMES = 1000000
Benchmark.bmbm do |r|
r.report("numeric round_to (float)") { TIMES.times { num.round_to(place) } }
r.report("numeric round_to (to string)") { TIMES.times { num.round_to(place).to_s } }
r.report("sprintf (float)") { TIMES.times { num.round_to_sprintf_f(place) } }
r.report("sprintf (string)") { TIMES.times { num.round_to_sprintf_sprintf(place) } }
r.report("sprintf modulus (string)") { TIMES.times { num.round_to_sprintf_modulus(place) } }
end
The output:
% ruby -v
ruby 1.9.1p378 (2010-01-10 revision 26273) [x86_64-linux]
...
user system total real
numeric round_to (float) 0.820000 0.000000 0.820000 ( 0.819920)
numeric round_to (to string) 1.990000 0.000000 1.990000 ( 1.989912)
sprintf (float) 3.620000 0.000000 3.620000 ( 3.614758)
sprintf (string) 2.650000 0.000000 2.650000 ( 2.654812)
sprintf modulus (string) 3.190000 0.000000 3.190000 ( 3.191807)
The conclusion: Regardless of whether you are going to a string or numeric after rounding, it is faster to round numerically than with sprintf. Also, using the sprintf function is faster than '%'. Usually speed doesn't matter, but when it does...
No comments:
Post a Comment