-
Notifications
You must be signed in to change notification settings - Fork 195
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
Is it normal that to_string() for bigint takes so much(8-10 mins)? #79
Comments
Converting such a large binary number to decimal requires a lot of division by 10 (or powers of 10). I measured 560 seconds (9m20s) for this number from It's much faster to use hexadecimal -- less than 10ms. |
The ideea is that: |
We don't directly expose the data array, because we may change the internal details in the future, like choosing a different word size. However, if you enable the "serde" feature of This is quite fast, and also has the advantage that you can simply deserialize it. Any other serde format will work for this too. |
decimal conversion takes so long because bigint doesn't use an efficient algorithm. using the Schönhage–Strassen algorithm for multiplication with Newton's method for division along with recursive subdivision for the base conversion should improve the algorithm to From what I recall, the currently implemented algorithm has |
PRs welcome! |
I read the source code of bc then I found that the reason why it outputs numbers so fast is that bc uses decimal digits representation internally... |
Well, if I just tried using libgmp (through python3 with gmpy2), converting from gmpy2 import mpz
len((mpz(1) << 33219280).digits()) I know for a fact that libgmp uses either base 2^32 or 2^64 internally. |
This will get fixed by #169. |
Thanks 👍 |
For display purposes, we often types we don't care about the exact value, but we want a visual representation of some sort.For example I'm using bigint in solang, and if the source code is: contract C {
uint public a = 0x42 << 0x1000;
} The error message is:
How about a
Not sure on the exact format - suggestions welcome. |
Would the project consider accepting a PR that changes the pub struct BigInt<T: BigIntFormatting = Short> {
sign: Sign,
data: BigUint,
formatter: PhantomData<T>,
} In order to provide a "fast" default that prints normally only up until an acceptable size and uses scientific notation beyond that, but users still retain the ability to opt-into the current behavior relatively easily. I find this slightly better than All of this wouldn't be needed if Rust had custom formatting specifiers, but that's not the Rust we have today :) |
I think a type parameter would be way too intrusive. I also think that defaulting to an abbreviated form would be a surprising change for the "unaware" on the other end of the spectrum. |
@cuviper would the prior suggestion of a new method with conditional formatting predicated on a length check be acceptable instead? |
Let's maybe start with an abbreviated form, and leave conditionals external for now. I fear that might still be somewhat slow to find the upper decimal digits, but maybe it can discard a lot with large divisors. I'm open to experimentation. |
Well, i have an big int with ~50K digits. And when i want to print it/write it to file, to_string() takes very much. Is there a way to boost this?
P.s. i'm using --release
P.P.s this number is result for calculating factorial(1000000)
The text was updated successfully, but these errors were encountered: