Optimizing a bigint fibonacci
Biotronic
simen.kjaras at gmail.com
Wed Dec 6 10:00:48 UTC 2017
On Wednesday, 6 December 2017 at 09:12:08 UTC, helxi wrote:
> This is question not directly related to language concepts,
> it's got more to do with the application. I would appreciate if
> anyone would point to me how I could optimize this bit of code
Here's my version:, based on fast squaring:
auto fib(ulong n) {
import std.bigint : BigInt;
import std.meta : AliasSeq;
import std.typecons : tuple;
BigInt a = 0;
BigInt b = 1;
auto bit = 63;
while (bit > 0) {
AliasSeq!(a, b) = tuple(
a * (2*b - a),
a*a + b*b);
if (n & (BigInt(1) << bit)) {
AliasSeq!(a, b) = tuple(b, a+b);
}
--bit;
}
return a;
}
unittest {
import std.stdio : writeln;
import std.datetime : MonoTime;
auto t0 = MonoTime.currTime;
writeln(fib(10_000_000));
writeln(MonoTime.currTime - t0);
}
Takes around 600 milliseconds to compute fib(1_000_000), and 50
seconds for fib(10_000_000).
Fast squaring algorithm found and described here:
https://www.nayuki.io/page/fast-fibonacci-algorithms
> I also noticed that if I try to compute it in the compile time
> with enum x = fib(100000) the compiler freezes. What could
> cause this?
That's because the poor compiler isn't as good at optimizing
compile-time code as run-time code, and because fib(100000) is
frigging ginormous.
--
Biotronic
More information about the Digitalmars-d-learn
mailing list