…nto foreach
For:
<?php
function plus1($x) {
return $x + 1;
}
$array = array_fill(0, 100, 1);
$count = 0;
for ($i = 0; $i < 100_000; $i++) {
$count += count(array_map(plus1(...), $array));
}
var_dump($count);
This is ~1.1× faster:
Benchmark 1: /tmp/test/before -d opcache.enable_cli=1 /tmp/test/test6.php
Time (mean ± σ): 172.2 ms ± 0.5 ms [User: 167.8 ms, System: 4.2 ms]
Range (min … max): 171.6 ms … 173.1 ms 17 runs
Benchmark 2: /tmp/test/after -d opcache.enable_cli=1 /tmp/test/test6.php
Time (mean ± σ): 155.1 ms ± 1.3 ms [User: 150.6 ms, System: 4.2 ms]
Range (min … max): 154.2 ms … 159.3 ms 18 runs
Summary
/tmp/test/after -d opcache.enable_cli=1 /tmp/test/test6.php ran
1.11 ± 0.01 times faster than /tmp/test/before -d opcache.enable_cli=1 /tmp/test/test6.php
With JIT it becomes ~1.7× faster:
Benchmark 1: /tmp/test/before -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php
Time (mean ± σ): 166.9 ms ± 0.6 ms [User: 162.7 ms, System: 4.1 ms]
Range (min … max): 166.1 ms … 167.9 ms 17 runs
Benchmark 2: /tmp/test/after -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php
Time (mean ± σ): 94.5 ms ± 2.7 ms [User: 90.4 ms, System: 3.9 ms]
Range (min … max): 92.5 ms … 103.1 ms 31 runs
Summary
/tmp/test/after -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php ran
1.77 ± 0.05 times faster than /tmp/test/before -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php
This was referenced
Jan 21, 2026Closed
Closed
TimWolla added a commit to TimWolla/php-src that referenced this pull request
Jan 23, 2026Following php#20934 which introduced the OPcode.
Merged
TimWolla added a commit that referenced this pull request
Jan 23, 2026Following #20934 which introduced the OPcode.
Merged
Open
adrian-enspired pushed a commit to adrian-enspired/php-src that referenced this pull request
Aug 4, 2026…nto foreach (php#20934) * zend_compile: Optimize `array_map()` with callable convert callback into foreach For: <?php function plus1($x) { return $x + 1; } $array = array_fill(0, 100, 1); $count = 0; for ($i = 0; $i < 100_000; $i++) { $count += count(array_map(plus1(...), $array)); } var_dump($count); This is ~1.1× faster: Benchmark 1: /tmp/test/before -d opcache.enable_cli=1 /tmp/test/test6.php Time (mean ± σ): 172.2 ms ± 0.5 ms [User: 167.8 ms, System: 4.2 ms] Range (min … max): 171.6 ms … 173.1 ms 17 runs Benchmark 2: /tmp/test/after -d opcache.enable_cli=1 /tmp/test/test6.php Time (mean ± σ): 155.1 ms ± 1.3 ms [User: 150.6 ms, System: 4.2 ms] Range (min … max): 154.2 ms … 159.3 ms 18 runs Summary /tmp/test/after -d opcache.enable_cli=1 /tmp/test/test6.php ran 1.11 ± 0.01 times faster than /tmp/test/before -d opcache.enable_cli=1 /tmp/test/test6.php With JIT it becomes ~1.7× faster: Benchmark 1: /tmp/test/before -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php Time (mean ± σ): 166.9 ms ± 0.6 ms [User: 162.7 ms, System: 4.1 ms] Range (min … max): 166.1 ms … 167.9 ms 17 runs Benchmark 2: /tmp/test/after -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php Time (mean ± σ): 94.5 ms ± 2.7 ms [User: 90.4 ms, System: 3.9 ms] Range (min … max): 92.5 ms … 103.1 ms 31 runs Summary /tmp/test/after -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php ran 1.77 ± 0.05 times faster than /tmp/test/before -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php * zend_compile: Skip `assert(...)` callbacks for array_map() optimization * zend_compile: Remove `zend_eval_const_expr()` in array_map optimization * zend_vm_def: Check simple types without loading the arginfo in ZEND_TYPE_ASSERT * zend_vm_def: Handle references for ZEND_TYPE_ASSERT * zend_compile: Fix handling of constant arrays for `array_map()` * zend_compile: Fix leak of unused result in array_map() optimization * zend_compile: Support static methods for `array_map()` optimization * UPGRADING
adrian-enspired pushed a commit to adrian-enspired/php-src that referenced this pull request
Aug 4, 2026Following php#20934 which introduced the OPcode.