-
Notifications
You must be signed in to change notification settings - Fork 445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce PerformanceOptimizedDelegateCalculator #747
Introduce PerformanceOptimizedDelegateCalculator #747
Conversation
* | ||
* @psalm-immutable | ||
*/ | ||
final class PerformanceOptimizedDelegateCalculator implements Calculator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.