Introduce PerformanceOptimizedDelegateCalculator#747
Conversation
| * | ||
| * @psalm-immutable | ||
| */ | ||
| final class PerformanceOptimizedDelegateCalculator implements Calculator |
There was a problem hiding this comment.
We probably need to expand https://github.com/moneyphp/money/tree/8953b873725c465bc55eee12a1c91b923e0d63c7/benchmark to include the raw calculators (as 3 almost-exactly-same benchmark classes)
cd72c9a to
fdfd57c
Compare
|
@Ocramius @frederikbosch Added calculator benchmarks. Unfortunately I fail to replicate the improved add/substract performance on calculator level. I have to recheck my setup. |
|
That's quite an improvement! Some performance overhead due to delegated method calls, but overall OK 👍 |
|
I really can't make sense of the following. When calling final class CompareCalculatorsBench
{
public function benchAddBcMath(): void
{
Money::registerCalculator(BcMathCalculator::class);
$currency = new Currency('EUR');
$a = new Money('100', $currency);
$b = new Money('50', $currency);
$a->add($b);
}
public function benchAddGmp(): void
{
Money::registerCalculator(GmpCalculator::class);
$currency = new Currency('EUR');
$a = new Money('100', $currency);
$b = new Money('50', $currency);
$a->add($b);
}
public function benchAddCalculatorBcMatch(): void
{
BcMathCalculator::add('100', '50');
}
public function benchAddCalculatorGmp(): void
{
GmpCalculator::add('100', '50');
}
}$ composer benchmark -- benchmark/CompareCalculatorsBench.php
> vendor/bin/phpbench run --retry-threshold=3 --iterations=15 --revs=1000 --warmup=2 'benchmark/CompareCalculatorsBench.php'
PHPBench (1.2.10) running benchmarks... #standwithukraine
with configuration file: /home/pushapidev/current/moneyphp/phpbench.json
with PHP version 8.1.17, xdebug ❌, opcache ✔
\Benchmark\Money\CompareCalculatorsBench
benchAddBcMath..........................R2 I4 - Mo0.872μs (±0.90%)
benchAddGmp.............................R1 I3 - Mo0.664μs (±1.00%)
benchAddCalculatorBcMatch...............R1 I11 - Mo0.125μs (±1.27%)
benchAddCalculatorGmp...................R1 I10 - Mo0.208μs (±1.17%)
Subjects: 4, Assertions: 0, Failures: 0, Errors: 0 |
|
OK, turns out Gmp is in fact slower than BcMath for add operations. The increased performance of // \Money\Calculator\BcMathCalculator::add
bcadd('50', '100', 14);
// Return: string(18) "150.00000000000000"
// \Money\Calculator\GmpCalculator::add
gmp_strval(gmp_add('50', '100'));
// Return: string(3) "150"The result is passed into the The result representation is critical for the code path in public function __construct(int|string $amount, Currency $currency)
{
$this->currency = $currency;
if (filter_var($amount, FILTER_VALIDATE_INT) === false) {
$numberFromString = Number::fromString((string) $amount);
if (! $numberFromString->isInteger()) {
throw new InvalidArgumentException('Amount must be an integer(ish) value');
}
$this->amount = $numberFromString->getIntegerPart();
return;
}
$this->amount = (string) $amount;
}The result of The results of This is very good news. We can easily improve the default |
|
It's maybe better to close this PR and open a fresh one with only the improved BCMatchCalculator. Edit: |
Reference: #634 (comment)
Benchmark with added
\Money\Money::registerCalculator(\Money\Calculator\PerformanceOptimizedDelegateCalculator::class);invendor/autoload.php:This is a weird outlier as the method is not affected by the calculator at all.