Closed imirkin closed 1 year ago
As of commit b356299808b8aaad38c518db64906dfa506b3aa2, the situation is much better. With the original value (which was my mashing the keyboard randomly):
987234798234987324987n
:
BigDecimal#toFixed x 2,805,997 ops/sec ±0.90% (87 runs sampled)
Decimal#toFixed x 3,020,014 ops/sec ±0.37% (89 runs sampled)
Fastest is Decimal#toFixed
BigDecimal#toString x 3,050,931 ops/sec ±0.99% (87 runs sampled)
Decimal#toString x 12,321,508 ops/sec ±0.98% (88 runs sampled)
Fastest is Decimal#toString
And with 100e12
:
BigDecimal#toFixed x 2,687,047 ops/sec ±0.55% (89 runs sampled)
Decimal#toFixed x 1,734,609 ops/sec ±1.07% (92 runs sampled)
Fastest is BigDecimal#toFixed
BigDecimal#toString x 2,277,608 ops/sec ±0.89% (91 runs sampled)
Decimal#toString x 3,057,007 ops/sec ±0.70% (86 runs sampled)
Fastest is Decimal#toString
So ... much more competitive. I need to do some more checks, but I don't know if it's worthwhile doing much more on this -- the other operations are all way faster, and toFixed
is a lot more important to me than toString
, which is either faster or on par with decimal.js.
With latest master (e4c3f3ee588ad4244664af353972c6a15bd5cef2), looks like this is winning (or on par) with both decimal.js and big.js (which somehow have different perf characteristics):
BigDecimal.BigDecimal x 1,012,460 ops/sec ±1.43% (91 runs sampled)
Decimal#constructor x 438,019 ops/sec ±0.50% (97 runs sampled)
Big#constructor x 677,697 ops/sec ±0.95% (91 runs sampled)
Fastest is BigDecimal.BigDecimal
BigDecimal#toFixed x 843,683 ops/sec ±0.82% (96 runs sampled)
Decimal#toFixed x 626,912 ops/sec ±1.01% (95 runs sampled)
Big#toFixed x 656,388 ops/sec ±1.74% (94 runs sampled)
Fastest is BigDecimal#toFixed
BigDecimal#toString x 2,664,587 ops/sec ±0.60% (94 runs sampled)
Decimal#toString x 2,574,290 ops/sec ±0.52% (95 runs sampled)
Big#toString x 1,353,320 ops/sec ±0.38% (95 runs sampled)
Fastest is BigDecimal#toString
For the values
let vals = [
"98.987432987",
"100000000000.00",
"987344785.36",
"1",
];
I put together a quick benchmark as I was noticing that toString/toFixed felt slow.
Click to expand benchmark
```js import Benchmark from 'benchmark'; import {BigDecimal} from './BigDecimal.js'; import {default as BigDecimal2} from './BigDecimalByDecimal.js.js'; var suite = new Benchmark.Suite; let big = BigDecimal.BigDecimal(987234798234987324987n); let decimal = BigDecimal2.BigDecimal(987234798234987324987n); // add tests suite.add('BigDecimal#toFixed', function() { big.toFixed(0); }) .add('Decimal#toFixed', function() { decimal.toFixed(0); }) // add listeners .on('cycle', function(event) { console.log(String(event.target)); }) .on('complete', function() { console.log('Fastest is ' + this.filter('fastest').map('name')); }) // run async .run({ 'async': false }); var suite = new Benchmark.Suite; // add tests suite.add('BigDecimal#toString', function() { big.toString(); }) .add('Decimal#toString', function() { decimal.toString(); }) // add listeners .on('cycle', function(event) { console.log(String(event.target)); }) .on('complete', function() { console.log('Fastest is ' + this.filter('fastest').map('name')); }) // run async .run({ 'async': false }); ```The results aren't great:
I'm running this on an ancient CPU (Intel Core i7-920), but I doubt that the lack of AVX/AVX2 is what's doing me in here. Feel free to try out the above benchmark code after doing
npm i benchmark
, perhaps CPU type really does play into it. In case it matters, I'm using node v20.2.0, although the ultimate target is a web browser.I'll be digging into the implementation of both this and decimal.js/big.js to see what can be copied/changed, or if there are any obvious shortcomings, but also very much open to suggestions.
I did notice that
10n ** n
is faster when the power is large (e.g. 100), but slower for smaller powers (e.g. 10) thanBigInt("1" + "0".repeat(n))
. But I doubt that's the whole story.