1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00
Files
archived-php-src/ext/standard/tests/strings/sprintf_rope_optimization_003.phpt
Tim Düsterhus 2c5ed50d5c zend_compile: Add support for %d to sprintf() optimization (#14561)
* zend_compile: Rename `string_placeholder_count` to `placeholder_count` in `zend_compile_func_sprintf()`

This is intended to make the diff of a follow-up commit smaller.

* zend_compile: Add support for `%d` to `sprintf()` optimization

This extends the existing `sprintf()` optimization by support for the `%d`
placeholder, which effectively equivalent to an `(int)` cast followed by a
`(string)` cast.

For a synthetic test using:

    <?php

    $a = 'foo';
    $b = 42;

    for ($i = 0; $i < 100_000_000; $i++) {
        sprintf("%s-%d", $a, $b);
    }

This optimization yields a 1.3× performance improvement:

    $ hyperfine 'sapi/cli/php -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php' \
          '/tmp/unoptimized -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php'
    Benchmark 1: sapi/cli/php -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php
      Time (mean ± σ):      3.296 s ±  0.094 s    [User: 3.287 s, System: 0.005 s]
      Range (min … max):    3.213 s …  3.527 s    10 runs

    Benchmark 2: /tmp/unoptimized -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php
      Time (mean ± σ):      4.300 s ±  0.025 s    [User: 4.290 s, System: 0.007 s]
      Range (min … max):    4.266 s …  4.334 s    10 runs

    Summary
      sapi/cli/php -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php ran
        1.30 ± 0.04 times faster than /tmp/unoptimized -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php

* Fix sprintf_rope_optimization_003.phpt test expecation for 32-bit integers

* zend_compile: Indent switch-case labels in zend_compile_func_sprintf()

* Add GMP test to sprintf() rope optimization

* Add `%s` test case to sprintf() GMP test
2024-06-17 17:07:50 +02:00

135 lines
2.9 KiB
PHP

--TEST--
Test sprintf() function : Rope Optimization for '%d'.
--FILE--
<?php
function func($num) {
return $num + 1;
}
function sideeffect() {
echo "Called!\n";
return "foo";
}
class Foo {
public function __construct() {
echo "Called\n";
}
}
$a = 42;
$b = -1337;
$c = 3.14;
$d = new stdClass();
try {
var_dump(sprintf("%d", $a));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("%d/%d", $a, $b));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("%d/%d/%d", $a, $b, $c));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("%d/%d/%d/%d", $a, $b, $c, $d));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("%d/", func(0)));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("/%d", func(0)));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("/%d/", func(0)));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("%d/%d/%d/%d", $a, $b, func(0), $a));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("%d/%d/%d/%d", __FILE__, __LINE__, 1, M_PI));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("%d/%d/%d", new Foo(), new Foo(), new Foo(), ));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf('%d/%d/%d', [], [], []));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
if (PHP_INT_SIZE == 8) {
var_dump(sprintf('%d/%d/%d', PHP_INT_MAX, 0, PHP_INT_MIN));
var_dump("2147483647/0/-2147483648");
} else {
var_dump("9223372036854775807/0/-9223372036854775808");
var_dump(sprintf('%d/%d/%d', PHP_INT_MAX, 0, PHP_INT_MIN));
}
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf('%d/%d/%d', true, false, true));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("%d/%d", true, 'foo'));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
try {
var_dump(sprintf("%d", 'foo'));
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
echo "Done";
?>
--EXPECTF--
string(2) "42"
string(8) "42/-1337"
string(10) "42/-1337/3"
Warning: Object of class stdClass could not be converted to int in %s on line 33
string(12) "42/-1337/3/1"
string(2) "1/"
string(2) "/1"
string(3) "/1/"
string(13) "42/-1337/1/42"
string(8) "0/53/1/3"
Called
Called
Called
Warning: Object of class Foo could not be converted to int in %s on line 57
Warning: Object of class Foo could not be converted to int in %s on line 57
Warning: Object of class Foo could not be converted to int in %s on line 57
string(5) "1/1/1"
string(5) "0/0/0"
string(42) "9223372036854775807/0/-9223372036854775808"
string(24) "2147483647/0/-2147483648"
string(5) "1/0/1"
string(3) "1/0"
string(1) "0"
Done