Skip to content

ext/bcmath: Performance improvement bcsqrt() #18771

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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

SakiTakamachi
Copy link
Member

@SakiTakamachi SakiTakamachi commented Jun 5, 2025

Test

Approximately 80 million calculations were performed using values of various magnitudes and scales, and all results matched those from the previous implementation.

Benchmark

Performance improvements are particularly noticeable in the following cases:

  • When dealing with small values (due to the use of a fast path)
  • When handling decimal numbers less than 1 with many leading zeros (as leading zeros are removed before computation)
  • When the scale of the input number (num) is much larger than the required result scale (since unnecessary fractional digits are now ignored during computation)

For large values that do not fall into the above categories, most of the execution time is spent on the iterative process of the Newton-Raphson method, especially on division operations. As a result, while there may be some minor gains from reducing memory allocations and lowering the cost of converting BCD to BC_VECTOR, there is no significant improvement in overall performance.

Small size value (fast path)

Code:

for ($i = 0; $i < 1000000; $i++) {
    bcsqrt(20, 6);
}

Result:

Benchmark 1: /php-dev2/sapi/cli/php /mount/bc/sqrt/0.php
  Time (mean ± σ):      65.9 ms ±   0.8 ms    [User: 60.4 ms, System: 3.2 ms]
  Range (min … max):    64.1 ms …  67.3 ms    46 runs
 
Benchmark 2: /master/sapi/cli/php /mount/bc/sqrt/0.php
  Time (mean ± σ):     746.1 ms ±   4.4 ms    [User: 740.2 ms, System: 3.5 ms]
  Range (min … max):   741.5 ms … 756.3 ms    10 runs
 
Summary
  '/php-dev2/sapi/cli/php /mount/bc/sqrt/0.php' ran
   11.32 ± 0.15 times faster than '/master/sapi/cli/php /mount/bc/sqrt/0.php'

Middle size value (< 1) (standard path)

Code:

for ($i = 0; $i < 500000; $i++) {
    bcsqrt('0.000045689101', 20);
}

Result:

Benchmark 1: /php-dev2/sapi/cli/php /mount/bc/sqrt/1.php
  Time (mean ± σ):     108.0 ms ±   0.3 ms    [User: 102.5 ms, System: 3.2 ms]
  Range (min … max):   107.5 ms … 108.8 ms    27 runs
 
Benchmark 2: /master/sapi/cli/php /mount/bc/sqrt/1.php
  Time (mean ± σ):      1.082 s ±  0.002 s    [User: 1.076 s, System: 0.003 s]
  Range (min … max):    1.078 s …  1.085 s    10 runs
 
Summary
  '/php-dev2/sapi/cli/php /mount/bc/sqrt/1.php' ran
   10.01 ± 0.04 times faster than '/master/sapi/cli/php /mount/bc/sqrt/1.php'

Middle size value 1 (fast path)

The new logic ignores unnecessary scales in the calculation, so this is a fast path.

Code:

for ($i = 0; $i < 700000; $i++) {
    bcsqrt('15151324141414.412312232141241', 0);
}

Result:

Benchmark 1: /php-dev2/sapi/cli/php /mount/bc/sqrt/2.php
  Time (mean ± σ):      55.0 ms ±   2.4 ms    [User: 49.6 ms, System: 3.1 ms]
  Range (min … max):    52.6 ms …  71.1 ms    53 runs

Benchmark 2: /master/sapi/cli/php /mount/bc/sqrt/2.php
  Time (mean ± σ):      1.099 s ±  0.003 s    [User: 1.092 s, System: 0.004 s]
  Range (min … max):    1.093 s …  1.102 s    10 runs
 
Summary
  '/php-dev2/sapi/cli/php /mount/bc/sqrt/2.php' ran
   19.98 ± 0.89 times faster than '/master/sapi/cli/php /mount/bc/sqrt/2.php'

Middle size value 2 (standard path)

Code:

for ($i = 0; $i < 500000; $i++) {
    bcsqrt('15151324141414.412312232141241', 30);
}

Result:

Benchmark 1: /php-dev2/sapi/cli/php /mount/bc/sqrt/3.php
  Time (mean ± σ):     204.1 ms ±   0.8 ms    [User: 198.5 ms, System: 3.3 ms]
  Range (min … max):   202.7 ms … 205.9 ms    14 runs
 
Benchmark 2: /master/sapi/cli/php /mount/bc/sqrt/3.php
  Time (mean ± σ):      1.315 s ±  0.034 s    [User: 1.308 s, System: 0.003 s]
  Range (min … max):    1.297 s …  1.411 s    10 runs

Summary
  '/php-dev2/sapi/cli/php /mount/bc/sqrt/3.php' ran
    6.44 ± 0.17 times faster than '/master/sapi/cli/php /mount/bc/sqrt/3.php'

Big size value (standard path)

Code:

for ($i = 0; $i < 100; $i++) {
    bcsqrt('15151324141414.412312232141241', 3000);
}

Result:

Benchmark 1: /php-dev2/sapi/cli/php /mount/bc/sqrt/4.php
  Time (mean ± σ):     195.7 ms ±   1.8 ms    [User: 189.7 ms, System: 3.4 ms]
  Range (min … max):   194.2 ms … 201.8 ms    15 runs

Benchmark 2: /master/sapi/cli/php /mount/bc/sqrt/4.php
  Time (mean ± σ):     280.0 ms ±   4.5 ms    [User: 274.3 ms, System: 3.2 ms]
  Range (min … max):   276.2 ms … 289.2 ms    10 runs
 
Summary
  '/php-dev2/sapi/cli/php /mount/bc/sqrt/4.php' ran
    1.43 ± 0.03 times faster than '/master/sapi/cli/php /mount/bc/sqrt/4.php'

@SakiTakamachi SakiTakamachi force-pushed the bcmath/optimize_sqrt branch 7 times, most recently from bbfe6d5 to 9cf6b03 Compare June 6, 2025 13:05
@SakiTakamachi SakiTakamachi changed the title [WIP] ext/bcmath: optimized sqrt() [WIP] ext/bcmath: optimized bcsqrt() Jun 7, 2025
@SakiTakamachi SakiTakamachi force-pushed the bcmath/optimize_sqrt branch 21 times, most recently from bd573f4 to b60f757 Compare June 9, 2025 01:55
@SakiTakamachi SakiTakamachi force-pushed the bcmath/optimize_sqrt branch 7 times, most recently from 03f3124 to 8d619bd Compare June 10, 2025 06:01
@SakiTakamachi SakiTakamachi changed the title [WIP] ext/bcmath: optimized bcsqrt() ext/bcmath: Performance improvement bcsqrt() Jun 10, 2025
@SakiTakamachi SakiTakamachi marked this pull request as ready for review June 10, 2025 06:49
@SakiTakamachi SakiTakamachi marked this pull request as draft June 10, 2025 06:53
@SakiTakamachi
Copy link
Member Author

Sorry, it was still incomplete.

@SakiTakamachi SakiTakamachi force-pushed the bcmath/optimize_sqrt branch 6 times, most recently from 193a1a5 to 9c4af5c Compare June 11, 2025 06:40
@SakiTakamachi SakiTakamachi force-pushed the bcmath/optimize_sqrt branch from 9c4af5c to 70613a0 Compare June 11, 2025 06:43
@SakiTakamachi SakiTakamachi force-pushed the bcmath/optimize_sqrt branch from 70613a0 to d7d1d80 Compare June 11, 2025 07:55
@SakiTakamachi SakiTakamachi marked this pull request as ready for review June 11, 2025 09:04
@SakiTakamachi
Copy link
Member Author

The code is ready for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant