Details
-
Type:
Improvement
-
Status:
Resolved
-
Priority:
Minor
-
Resolution: Won't Fix
-
Affects Version/s: JRuby 1.4
-
Fix Version/s: None
-
Component/s: Core Classes/Modules
-
Labels:None
-
Environment:Mac OS X 10.6.3
-
Number of attachments :
Description
BigDecimal#log is performance-broken for arguments x with x < 0.1 or x > 10. This is an old issue, see for example Ruby Cookbook, O'Reilly 2006. Their fix is several times faster for small or large arguments:
require "bigdecimal"
require "bigdecimal/math"
require "benchmark"
include BigMath
module BigMath
def fast_log(x, prec)
sign, fraction, power, exponent = x.split
fraction = BigDecimal("0.#{fraction}")
power = BigDecimal("#{power}")
log(fraction, prec) + (log(power, prec) * exponent)
end
end
prec = 100
Benchmark.bmbm(15) do |results|
results.report("fast_log 0.0001:") { BigMath.fast_log(BigDecimal("0.0001"), prec) }
results.report("fast_log 0.001:") { BigMath.fast_log(BigDecimal("0.001"), prec) }
results.report("fast_log 1000:") { BigMath.fast_log(BigDecimal("1000"), prec) }
results.report("fast_log 10000:") { BigMath.fast_log(BigDecimal("10000"), prec) }
results.report("log 0.0001:") { BigMath.log(BigDecimal("0.0001"), prec) }
results.report("log 0.001:") { BigMath.log(BigDecimal("0.001"), prec) }
results.report("log 1000:") { BigMath.log(BigDecimal("1000"), prec) }
results.report("log 10000:") { BigMath.log(BigDecimal("10000"), prec) }
end
jruby 1.5.0.RC3 (ruby 1.8.7 patchlevel 249) (2010-05-04 603f15a) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_17) [x86_64-java]
user system total real
fast_log 0.0001: 0.019000 0.000000 0.019000 ( 0.018000)
fast_log 0.001: 0.030000 0.000000 0.030000 ( 0.030000)
fast_log 1000: 0.019000 0.000000 0.019000 ( 0.019000)
fast_log 10000: 0.018000 0.000000 0.018000 ( 0.019000)
log 0.0001: 7.050000 0.000000 7.050000 ( 7.050000)
log 0.001: 0.687000 0.000000 0.687000 ( 0.687000)
log 1000: 0.673000 0.000000 0.673000 ( 0.673000)
log 10000: 6.658000 0.000000 6.658000 ( 6.658000)
I haven't tested the code here, but what's the license for its use? (Is the link you provided licensed to distribute O'Reilly's content?)
BigDecimal.log is a part of MRI's standard library, so I tend to shy away from overriding it unless there is a good reason. Assuming that the suggested change is a good one, then, all the Ruby implementations will benefit if MRI took up the change.