a14n / dart-decimal

Apache License 2.0
178 stars 44 forks source link

Realize serious performance problems #109

Open feiquan666 opened 2 months ago

feiquan666 commented 2 months ago

It is recommended that you use big_decimal.

It is hoped that the author can read and deeply understand the implementation of Java's large number of calculations and use DART languages. Or abandon the update of this warehouse, so as not to cause unnecessary trouble for users who do not know the specific situation.

decimal Test

```dart
import 'package:decimal/decimal.dart';
import 'dart:core';

void main() {
  test(1);
  test(10);
  test(100);
  test(1000);
  test(10000);
}

void test(int loopTimes) {
  var t0 = DateTime.now();
  Decimal a = Decimal.parse('123456789.987654321');
  Decimal b = Decimal.parse('987654321.123456789');
  Decimal result = Decimal.parse("1");
  for (int i = 0; i < loopTimes; i++) {
    result = a * b * result;
  }
  var t1 = DateTime.now();
  print('Loop $loopTimes times,Cost: ${t1.difference(t0).inMilliseconds} ms');
}

```

Loop 1 times,Cost: 5 ms Loop 10 times,Cost: 11 ms Loop 100 times,Cost: 29 ms Loop 1000 times,Cost: 159250 ms Loop 10000 times,Cost: It took too long to test it

big_decimal Test

import 'package:big_decimal/big_decimal.dart';
import 'dart:core';

void main() {
  test(1);
  test(10);
  test(100);
  test(1000);
  test(10000);
  test(100000);
}

void test(int loopTimes) {
  var t0 = DateTime.now();
  BigDecimal a = BigDecimal.parse('123456789.987654321');
  BigDecimal b = BigDecimal.parse('987654321.123456789');
  BigDecimal result = BigDecimal.parse("1");
  for (int i = 0; i < loopTimes; i++) {
    result = a * b * result;
  }
  var t1 = DateTime.now();
  print('Loop $loopTimes times,Cost: ${t1.difference(t0).inMilliseconds} ms');
}

Loop 1 times,Cost: 2 ms Loop 10 times,Cost: 0 ms Loop 100 times,Cost: 0 ms Loop 1000 times,Cost: 7 ms Loop 10000 times,Cost: 363 ms Loop 100000 times,Cost: 42112 ms

Using Java BigDecimal

package cn.javaunion.practice.calcul;

import java.math.BigDecimal;

public class BigDecimalTest {

    public static void main(String[] args) {
        test(1);
        test(10);
        test(100);
        test(1000);
        test(10000);
        test(100000);
        test(1000000);
    }

    public static void test(int loopTimes) {
        var t0 = System.currentTimeMillis();
        BigDecimal a = new BigDecimal("123456789.987654321");
        BigDecimal b = new BigDecimal("987654321.123456789");
        BigDecimal result = new BigDecimal("1");
        for (int i = 0; i < loopTimes; i++) {
            result = a .multiply(b).multiply(result);
        }
        var t1 = System.currentTimeMillis();
        System.out.printf("Loop %s times,Cost: %s ms\n", loopTimes, (t1 - t0));
    }

}

Loop 1 times,Cost: 1 ms Loop 10 times,Cost: 1 ms Loop 100 times,Cost: 2 ms Loop 1000 times,Cost: 20 ms Loop 10000 times,Cost: 249 ms Loop 100000 times,Cost: 17558 ms

asinel commented 1 month ago

I ran the test and I confirm that there is an issue: decimal:

Loop 1 times,Cost: 5 ms
Loop 10 times,Cost: 2 ms
Loop 100 times,Cost: 74 ms
Loop 1000 times,Cost: 41150 ms

big_decimal:

Loop 1 times,Cost: 0 ms
Loop 10 times,Cost: 0 ms
Loop 100 times,Cost: 0 ms
Loop 1000 times,Cost: 4 ms
Loop 10000 times,Cost: 440 ms