Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use better initial guesses for Roots #71

Merged
merged 2 commits into from
Dec 14, 2018
Merged

Conversation

cuviper
Copy link
Member

@cuviper cuviper commented Dec 5, 2018

When a BigUint is small enough to fit in a u64, we use that to compute roots instead.

Otherwise, we can get a closer approximation of roots via f64. For values that are even too big for that, we can shift them down in multiples of n enough that they do fit, and then shift the result back and refine the answer further.

Benchmarked with an i7-7700K on Fedora 29, rustc 1.32.0-nightly (21f268495 2018-12-02).

 name             roots-master ns/iter  roots-opt ns/iter  diff ns/iter   diff %   speedup
 big1k_cbrt       18,787                6,934                   -11,853  -63.09%    x 2.71
 big1k_nth_10     20,896                4,595                   -16,301  -78.01%    x 4.55
 big1k_nth_100    53,912                1,326                   -52,586  -97.54%   x 40.66
 big1k_nth_1000   4,175                 5,205                     1,030   24.67%    x 0.80
 big1k_nth_10000  7,634                 23                       -7,611  -99.70%  x 331.91
 big1k_sqrt       19,083                9,804                    -9,279  -48.62%    x 1.95
 big2k_cbrt       46,799                20,917                  -25,882  -55.30%    x 2.24
 big2k_nth_10     27,959                12,296                  -15,663  -56.02%    x 2.27
 big2k_nth_100    77,422                7,430                   -69,992  -90.40%   x 10.42
 big2k_nth_1000   10,851                10,611                     -240   -2.21%    x 1.02
 big2k_nth_10000  7,963                 24                       -7,939  -99.70%  x 331.79
 big2k_sqrt       53,835                20,542                  -33,293  -61.84%    x 2.62
 big4k_cbrt       117,757               45,320                  -72,437  -61.51%    x 2.60
 big4k_nth_10     87,084                32,310                  -54,774  -62.90%    x 2.70
 big4k_nth_100    43,477                22,657                  -20,820  -47.89%    x 1.92
 big4k_nth_1000   101,478               102,153                     675    0.67%    x 0.99
 big4k_nth_10000  8,384                 24                       -8,360  -99.71%  x 349.33
 big4k_sqrt       142,891               48,711                  -94,180  -65.91%    x 2.93
 big64_cbrt       2,417                 59                       -2,358  -97.56%   x 40.97
 big64_nth_10     4,595                 84                       -4,511  -98.17%   x 54.70
 big64_sqrt       1,109                 37                       -1,072  -96.66%   x 29.97

Everything is a big win except nth_1000, but even the loss there is fast enough that I'm not worried. I doubt nth_root(1000) would realistically be used anyway -- I just wanted challenging cases.

@cuviper
Copy link
Member Author

cuviper commented Dec 14, 2018

bors r+

bors bot added a commit that referenced this pull request Dec 14, 2018
71: Use better initial guesses for Roots r=cuviper a=cuviper

When a `BigUint` is small enough to fit in a `u64`, we use that to compute roots instead.

Otherwise, we can get a closer approximation of roots via `f64`.  For values that are even too big for that, we can shift them down in multiples of `n` enough that they do fit, and then shift the result back and refine the answer further.

Benchmarked with an i7-7700K on Fedora 29, `rustc 1.32.0-nightly (21f268495 2018-12-02)`.

```
 name             roots-master ns/iter  roots-opt ns/iter  diff ns/iter   diff %   speedup
 big1k_cbrt       18,787                6,934                   -11,853  -63.09%    x 2.71
 big1k_nth_10     20,896                4,595                   -16,301  -78.01%    x 4.55
 big1k_nth_100    53,912                1,326                   -52,586  -97.54%   x 40.66
 big1k_nth_1000   4,175                 5,205                     1,030   24.67%    x 0.80
 big1k_nth_10000  7,634                 23                       -7,611  -99.70%  x 331.91
 big1k_sqrt       19,083                9,804                    -9,279  -48.62%    x 1.95
 big2k_cbrt       46,799                20,917                  -25,882  -55.30%    x 2.24
 big2k_nth_10     27,959                12,296                  -15,663  -56.02%    x 2.27
 big2k_nth_100    77,422                7,430                   -69,992  -90.40%   x 10.42
 big2k_nth_1000   10,851                10,611                     -240   -2.21%    x 1.02
 big2k_nth_10000  7,963                 24                       -7,939  -99.70%  x 331.79
 big2k_sqrt       53,835                20,542                  -33,293  -61.84%    x 2.62
 big4k_cbrt       117,757               45,320                  -72,437  -61.51%    x 2.60
 big4k_nth_10     87,084                32,310                  -54,774  -62.90%    x 2.70
 big4k_nth_100    43,477                22,657                  -20,820  -47.89%    x 1.92
 big4k_nth_1000   101,478               102,153                     675    0.67%    x 0.99
 big4k_nth_10000  8,384                 24                       -8,360  -99.71%  x 349.33
 big4k_sqrt       142,891               48,711                  -94,180  -65.91%    x 2.93
 big64_cbrt       2,417                 59                       -2,358  -97.56%   x 40.97
 big64_nth_10     4,595                 84                       -4,511  -98.17%   x 54.70
 big64_sqrt       1,109                 37                       -1,072  -96.66%   x 29.97
```

Everything is a big win except `nth_1000`, but even the loss there is fast enough that I'm not worried.  I doubt `nth_root(1000)` would realistically be used anyway -- I just wanted challenging cases.

Co-authored-by: Josh Stone <[email protected]>
@bors
Copy link
Contributor

bors bot commented Dec 14, 2018

Build succeeded

@bors bors bot merged commit a7ebdfb into rust-num:master Dec 14, 2018
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