BigInt performance comparison
I am wondering: if I know that I don't need more than 64-bit integers when running on web, should I go for BigInt or for fixnum for best performance?
On native, I will simply use int (as I said, I know I don't need more than 64-bit and on native, int is already 64-bit). But on web, I need to use one of BigInt and fixnum. It would be nice to have a performance comparison between the two.
I think the answer would depend very much on what operations you are using and which browser and browser version the code is running in.
Generally, I would expect fixnum.Int64 to be faster than BigInt, if only because the BigInt version would need the occasional .toSigned(64) to avoid huge values (which would definitely be slower).
It would be better to use stackoverflow for this kind of question, where more people might see the question.
@rakudrama I understand. I feel like the README should have a section for this. And I mean the case where only 64-bit precision is needed, without handling overflows.
If you think this should be investigated on a case by case basis, I can also close this issue.
My main fear was that fixnum is super slow since it is implemented in Dart code.
There is a benchmark in the sdk that you could run. It benchmarks only the parse and toString() operations, but it might be a starting point.
Perhaps you could benchmark your scenario both ways and report your findings here?
https://github.com/dart-lang/fixnum/issues/36#issuecomment-370108579 mentions that BigInt is significantly slower.
My own empirical tests indicate that that's still true. I tried implementing mt19937-64 with both BigInt and Int64, and the BigInt version takes ~2x as long even with compiled to native.
@jamesderlin I wonder if you would be willing share your BigInt and Int64 implementations?
@jamesderlin I wonder if you would be willing share your BigInt and Int64 implementations?
Okay, I've posted them to https://github.com/jamesderlin/dart_mt19937.
- Clone the repository.
- Check out the
unsupportedbranch. -
dart pub get - Run
bin/time_mt64.dart.
Running it through the VM, I get times like:
int (signed): 0:00:00.004528
Int64 (signed): 0:00:00.009105
BigInt: 0:00:00.049247
When compiled to an AOT .exe, I get times like:
int (signed): 0:00:00.003894
Int64 (signed): 0:00:00.024484
BigInt: 0:00:00.050144
Interestingly, the Int64 version is way faster with the VM than when AOT-compiled.
Hi James,
Thanks for sharing your code.
From some experimenting with the code I would characterize the relative performance of int:Int64:BigInt as 1:5:25 on JIT VM and 1:12:25 on AOT.
I did not call the call method, I rather just called nextInt64 to avoid conversions to BigInt, as I am most interested in the performance of the basic operations. Avoiding the BigInt conversions would make my measured time for int version lower.
On dart2js -O4, Int64:BigInt is also 1:5.
/cc @alexmarkov It is interesting that Int64 is 2.5x slower on AOT than JIT. Putting prefer-inline on _masked and _promote recovers most of the difference.