-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
support pre-allocation in BigInt ctor #21983
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
Conversation
What about creating a "BigInt" label? (or "bignum" to include |
I realized there are already "rationals" and "complex" labels, so sureley a "bignums" label seems deserved! |
This is a tiny change, I think only the API can be controversial: I would choose |
tests, docs? |
My last post was confusing: currently this PR defines a method to reserve at creation time a space big enough to store later a number with |
base/gmp.jl
Outdated
end | ||
|
||
# n is the number of bits to allocate | ||
function BigInt(::typeof(sizehint!), n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit of a strange API, IMO. How about BigInt(; sizehint::Int=0)
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's strange and I would rather not use this API. I would prefer a Val{:unitit}
or Val{:allocsize}
argument, or a dedicated type, or even Type{Bool}
. But I wanted to avoid a keyword argument because the goal of the PR is to make a small optimization, which becomes worse than the status quo with the overhead of keyword arguments. Currently b=BigInt()
takes 50 ns on my machine and calling realloc(b, 200)
from GMP on it costs 65ns; with a keyword arg, BigIng(sizehint=200)
takes about 180ns, and BigInt()
takes 120ns !; but BigInt(Val{:allocsize}, 200)
takes about 50ns. Those numbers vary with the sizehint parameter (200 here), but always show that a keyword arg would be a no-go if optimization is sought after.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keyword arguments are likely to get faster fairly soon, so we should avoid making too many ugly API choices as workarounds for them being slow now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok then I can wait for no-overhead keywords.
Now that keywords are fast, I reimplemented using the |
I will merge in a few days if no objection. The name of the keyword is rather inconsequential and remains for now an implementation detail. |
If this is a performance change, should run Nanosoldier before merging. |
@nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
There seems to be some real performance regressions. |
Not sure how much it would matter but should we wait after #32102 before testing performance? edit: it see it has been merged |
Note, it's only been merged into the backport branch. But yes, it is true that the benchmarks might not be completely reliable if the bignum lib is built with bad optimizations. |
I can't reproduce locally the regressions, let's try again. @nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
In the two nanosoldier runs, I kept regressions wich are worse by more than 2% than what the tolerance allows, and the intersection contains 6 benchmarks, which are all unrelated to |
The allows to initialize a
BigInt
with enough space to encode ann
-bits integer (so this is an optimization compared to the functionMPZ.realloc!
, so as to avoid allocating twice).This was initially implemented in #13815 and discussed there. It was suggested to make this functionality a method of
sizehint!
, but this has to be implemented in the inner constructor ofBigInt
, so I don't think it's possible. I don't mind the mecanism (I originally used a::Val{:allocbits}
, now::typeof(sizehint!)
), suggestions welcome!