Anything in the review queue?

Don nospam at nospam.com
Mon Mar 21 22:25:16 PDT 2011


Andrei Alexandrescu wrote:
> On 3/21/11 12:18 PM, dsimcha wrote:
>> == Quote from Don (nospam at nospam.com)'s article
>>>> Ok, I don't know much about how BigInts work under the hood.  I used a
>>>> fairly simple implementation of Euler's algorithm here.  Is there
>>>> something much more efficient for BigInts?
>>> Yes. Euler's algorithm performs very poorly for BigInts. In fact, you
>>> probably want to use the BinaryGCD algorithm even for builtins.
>>> There is a sub-quadratic algorithm for GCD, but it's very complicated.
>>> (It's not the one Kenny posted).
>>>>> I guess the primary question is:
>>>>> If there were a BigRational type, would you still want rational?
>>>>> Ie, are there use cases for rational over built-in types (rather 
>>>>> than it
>>>>> just being a workaround for a lack of a BigRational type)?
>>>>
>>>> My thoughts were that Rational would be **primarily** used with BigInt,
>>>> but occasionally, if you really know what you're doing with regard to
>>>> overflow, you could used fixed width as an optimization.
>>> This isn't sounding so promising.
>>> I hate to be saying that.
>>
>> I've thought about this some more.  The following **may** be a good 
>> way to
>> proceed.  I'd like Don's input, since I don't know in detail what he 
>> was planning.
>>
>> 1.  Review the design of my rational lib with a focus on whether 
>> sufficient
>> infrastructure for creating specializations without introducing 
>> breaking changes
>> is available.
>>
>> 2.  If no issues not related to the lack of specialization for BigInt 
>> are raised,
>> accept Rational into Phobos for now.
>>
>> 3.  At his leisure, Don can write a specialization of Rational 
>> specifically for
>> BigInt (or even just a specialization of gcd, if that's all that's 
>> needed).  Once
>> this is done, we include it as an optimization, but without changes to 
>> the
>> interface.  Every integer type except BigInt still uses the generic 
>> implementation.
>>
>> 4.  Maybe we provide hooks for specializing certain 
>> performance-critical things
>> like GCD, in case someone wants to use their own custom BigInt type 
>> with Rational
>> without having to modify the code for Phobos.  For example, a BigInt 
>> type might
>> optionally define a gcd() method.  Rational would look for this and 
>> use it if it
>> exists, or use the generic fallback algorithm otherwise.
> 
> I think by and large failure to define rational for BigInt in a way that 
> has many commonalities with rational for built-in integrals reflects a 
> failure of BigInt. By its very design, BigInt is supposed to 
> transparently replace integers.If this is largely the case, the design
> has succeeded. If the design of anything must be reworked essentially 
> from scratch to work with BigInt instead of int et al, then the 
> abstraction may be too porous to be useful.
> 
> There are a few approaches we can take from here. One is to define 
> certain traits that differentiate BigInt from other integrals (e.g. 
> preferAdditionToMultiplication or whatnot),  and then design Rational to
> use those traits. Another is of course to specialize the entire Rational 
> on BigInt. Third would be to specialize certain core routines (gcd and 
> friends) for BigInt and keep Rational agnostic.

You're missing something important here. Rational big integers are a 
very well defined area of research, with its own set of algorithms.
Although you can pretend a BigInt behaves as an int, and make a rational 
type, the performance will be pathetic, and everyone will laugh at you.

> Anyhow, BigInt should be cheap to copy (i.e. use refcounting). If there 
> are good reasons for which that's impossible, we should give up on the 
> dream of enacting that assumption throughout Phobos. Don?

Well, it uses copy-on-write so copying itself isn't expensive.
But temporaries are never going to be cheap. Things like bigint *= 
bigint is  NEVER an in-place operation (the size is twice as big, so a 
memory allocation is always required). Even bigint += bigint may trigger 
a memory allocation.
Refcounting might be better than copy-on-write, in the end, but probably 
not a huge win.
One thing which I will do eventually is implement the small-integer 
optimisation (so anything smaller than 31 bits/63 bits is stored inside 
the pointer and doesn't have any memory allocation at all). But that 
doesn't help the general case.


More information about the Digitalmars-d mailing list