-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
libstd: Implement BigInt and BigUint. Issue #37 #4198
Conversation
I'm excited about this. Looks cool. |
How does this compare to this? Presumably the rust-gmp bindings are faster, but this has the advantage of being pure rust. |
The usage of libgmp has some issues: http://hackage.haskell.org/trac/ghc/wiki/ReplacingGMPNotes#ReasonsforReplacingGMPastheBignumlibrary |
Awesome. I figured we'd bind to acme bignum (it's in rt/) but this looks like a pretty direct reimplementation in plain rust. I'm into it! |
@Lenny222: The only real problem with using it with rust is the licensing one (it can't be in the standard library), and it's awesome to have pure rust libraries for things like this to evolve the performance of the language as a whole. @dbaupp: gmp is very fast because it uses different algorithms for a task like multiplication based on the size of the input, so they have much better asymptotic performance than most other libraries (covered here). It's also full of hand-rolled assembly and years of optimization, so it would be quite hard to compete with it from a performance standpoint. I think it would be a better idea to compare against implementations that other languages use (Go, Haskell, Python, etc.) and work towards beating all of those 😉. |
Some of the missing Rust Shootout-benchmarks need big numbers. See #2776 |
I had also done a Big Integer implementation in parallel (https://github.com/ahmadsalim/rust-bigint), if it can be in any help. |
@ahmadsalim Thanks! The two major differences I see are that the @gifnksm implementation has both Let's consider this carefully. Some observations:
|
I think using gmp has function definitions like this:
The output can be the same variable as one of the inputs, or a different one. It will (for some operations) reuse the memory allocated for the output variable, whether or not the operation is actually in-place. Equivalents in rust:
An operation like
So basically, you just need a mutable in-place API and then a |
Thank you for the many comments. I try to reimplement If possible, I would like to implement in-place calculation that was pointed out by @thestinger. |
@gifnksm That seems to be the best solution, as you currently have an implementation of the optimized algorithms. |
I did simple benchmark tests. The result is https://gist.github.com/4360131#file-benchmark-result-txt . This benchmark has two tests for each languages. The first test My first impression is my implementation is very slow.
For now, I try to implement the Karatsuba radix conversion. |
@gifnksm The reason that Haskell does not strictly evaluate your functions are that the let-bindings themselves are lazy. ...
let fac = factorial n
return $! fac
... The second is to use bang patterns to strictly evaluate the variable at binding time: {-# LANGUAGE BangPatterns #-}
...
let !fac = factorial n
... Hopefully this answer will help you to do a more accurate comparison. |
@ahmadsalim Now, I'm elminating extra memory allocation operations. |
This looks like a good start! r+ from me. I'm sure we can optimize and improve over time, but the interface seems minimal and reasonable. |
Merged. Thanks for the thorough review @ahmadsalim, @gifnksm, @thestinger and everyone. |
Implement BigInt (arbitrary precision integer) type.