Skip to content

Conversation

@tompng
Copy link
Member

@tompng tompng commented Jan 28, 2026

Remove slow calculation of log(10).
Before: log(x) = log(10)*n + log(x/10**n)
After: log(x) = log(x/exp(logx_approx)) + logx_approx

This optimization is based on https://bugs.ruby-lang.org/issues/6857#note-4

code v4.0.1 master this PR
BigMath.log(123, 100) 0.000321832s 0.001606367s 0.000444787s
BigMath.log(123, 1000) 0.009101423s 0.011210634s 0.003876186s
BigMath.log(123, 10000) 2.029444s 0.1657416s 0.0709938s
BigMath.log(1.23, 100) 0.000144828s 0.000723668s 0.000388832s
BigMath.log(1.23, 1000) 0.00455668s 0.00524359s 0.00349395s
BigMath.log(1.23, 10000) 1.026394s 0.0884704s 0.0646281s

When prec is 100, master branch got few times slower than v4.0.1. This pull request will make a bit better.

Remove slow calculation of log(10).
Before: log(x) = log(10)*n + log(x/10**n)
After: log(x) = log(x/exp(logx_approx)) + logx_approx
if x > 1.01 || x < 0.99
# log(x) = log(x/exp(logx_approx)) + logx_approx
logx_approx = BigDecimal(BigDecimal::Internal.float_log(x), 0)
x = x.div(exp(logx_approx, prec2), prec2)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Precision of exp should be larger than prec2 - logx_approx.exponent.abs theoretically and also experimentally. Just using prec2 is simple and enough.

@tompng tompng merged commit bd4220f into ruby:master Jan 28, 2026
87 checks passed
@tompng tompng deleted the logx_reduce branch January 28, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant