I tested my profiler using https://gist.github.com/Girgias/e21b57cff72b8d05be06883d98552ee6 . The profiler is slightly modified to get information about which opcode is how much used. https://github.com/sj-i/php-profiler/tree/experiment-opcode-tracer
php --version
PHP 7.4.8 (cli) (built: Jul 27 2020 03:41:09) ( ZTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.8, Copyright (c), by Zend Technologies
time php ./n-body-test.php 50000000
sudo ./php-profiler inspector:trace -p 250359 >result
cat result | sort | uniq -c | sort -nr
The output is formatted like below.
[count of appearance in traces] [function] [file]([line])<[opcode]>
85297 <main> /home/sji/work/test/n-body-test.php(188)<60>
10369 NBodySystem::advance /home/sji/work/test/n-body-test.php(134)<12>
2918 NBodySystem::advance /home/sji/work/test/n-body-test.php(138)<28>
2637 NBodySystem::advance /home/sji/work/test/n-body-test.php(142)<28>
2184 NBodySystem::advance /home/sji/work/test/n-body-test.php(140)<28>
2158 NBodySystem::advance /home/sji/work/test/n-body-test.php(144)<28>
2137 NBodySystem::advance /home/sji/work/test/n-body-test.php(139)<28>
2130 NBodySystem::advance /home/sji/work/test/n-body-test.php(143)<28>
2038 NBodySystem::advance /home/sji/work/test/n-body-test.php(130)<82>
2037 NBodySystem::advance /home/sji/work/test/n-body-test.php(131)<82>
2006 NBodySystem::advance /home/sji/work/test/n-body-test.php(132)<82>
1804 NBodySystem::advance /home/sji/work/test/n-body-test.php(128)<45>
1669 NBodySystem::advance /home/sji/work/test/n-body-test.php(136)<4>
1661 NBodySystem::advance /home/sji/work/test/n-body-test.php(135)<129>
1644 NBodySystem::advance /home/sji/work/test/n-body-test.php(134)<1>
1623 NBodySystem::advance /home/sji/work/test/n-body-test.php(138)<82>
1611 NBodySystem::advance /home/sji/work/test/n-body-test.php(139)<3>
1543 NBodySystem::advance /home/sji/work/test/n-body-test.php(138)<3>
1518 NBodySystem::advance /home/sji/work/test/n-body-test.php(142)<3>
1515 NBodySystem::advance /home/sji/work/test/n-body-test.php(143)<3>
1513 NBodySystem::advance /home/sji/work/test/n-body-test.php(140)<3>
1499 NBodySystem::advance /home/sji/work/test/n-body-test.php(135)<61>
1493 NBodySystem::advance /home/sji/work/test/n-body-test.php(129)<82>
1493 NBodySystem::advance /home/sji/work/test/n-body-test.php(128)<20>
1426 NBodySystem::advance /home/sji/work/test/n-body-test.php(144)<3>
1418 NBodySystem::advance /home/sji/work/test/n-body-test.php(129)<81>
1351 NBodySystem::advance /home/sji/work/test/n-body-test.php(144)<82>
1350 NBodySystem::advance /home/sji/work/test/n-body-test.php(143)<82>
1305 NBodySystem::advance /home/sji/work/test/n-body-test.php(140)<82>
1236 NBodySystem::advance /home/sji/work/test/n-body-test.php(139)<82>
1231 NBodySystem::advance /home/sji/work/test/n-body-test.php(142)<82>
1231 NBodySystem::advance /home/sji/work/test/n-body-test.php(128)<34>
1220 NBodySystem::advance /home/sji/work/test/n-body-test.php(130)<2>
1131 NBodySystem::advance /home/sji/work/test/n-body-test.php(135)<117>
1114 NBodySystem::advance /home/sji/work/test/n-body-test.php(150)<28>
1076 NBodySystem::advance /home/sji/work/test/n-body-test.php(149)<28>
1072 NBodySystem::advance /home/sji/work/test/n-body-test.php(151)<28>
1050 NBodySystem::advance /home/sji/work/test/n-body-test.php(132)<2>
1020 NBodySystem::advance /home/sji/work/test/n-body-test.php(126)<78>
1014 NBodySystem::advance /home/sji/work/test/n-body-test.php(131)<2>
897 NBodySystem::advance /home/sji/work/test/n-body-test.php(148)<78>
888 NBodySystem::advance /home/sji/work/test/n-body-test.php(127)<190>
818 NBodySystem::advance /home/sji/work/test/n-body-test.php(129)<22>
808 NBodySystem::advance /home/sji/work/test/n-body-test.php(136)<3>
800 NBodySystem::advance /home/sji/work/test/n-body-test.php(132)<22>
798 NBodySystem::advance /home/sji/work/test/n-body-test.php(131)<22>
770 NBodySystem::advance /home/sji/work/test/n-body-test.php(130)<22>
769 NBodySystem::advance /home/sji/work/test/n-body-test.php(134)<22>
765 NBodySystem::advance /home/sji/work/test/n-body-test.php(151)<82>
703 NBodySystem::advance /home/sji/work/test/n-body-test.php(148)<42>
677 NBodySystem::advance /home/sji/work/test/n-body-test.php(128)<42>
668 NBodySystem::advance /home/sji/work/test/n-body-test.php(128)<1>
664 NBodySystem::advance /home/sji/work/test/n-body-test.php(127)<82>
647 NBodySystem::advance /home/sji/work/test/n-body-test.php(150)<82>
604 NBodySystem::advance /home/sji/work/test/n-body-test.php(136)<22>
598 <main> /home/sji/work/test/n-body-test.php(187)<20>
566 NBodySystem::advance /home/sji/work/test/n-body-test.php(149)<82>
428 sqrt <internal>(-1)<-1>
386 NBodySystem::advance /home/sji/work/test/n-body-test.php(151)<3>
383 NBodySystem::advance /home/sji/work/test/n-body-test.php(150)<3>
367 NBodySystem::advance /home/sji/work/test/n-body-test.php(126)<22>
358 NBodySystem::advance /home/sji/work/test/n-body-test.php(149)<3>
252 <main> /home/sji/work/test/n-body-test.php(188)<112>
179 NBodySystem::advance /home/sji/work/test/n-body-test.php(153)<62>
164 NBodySystem::advance /home/sji/work/test/n-body-test.php(124)<63>
155 NBodySystem::advance /home/sji/work/test/n-body-test.php(126)<82>
127 NBodySystem::advance /home/sji/work/test/n-body-test.php(148)<82>
127 NBodySystem::advance /home/sji/work/test/n-body-test.php(148)<77>
125 NBodySystem::advance /home/sji/work/test/n-body-test.php(148)<127>
123 NBodySystem::advance /home/sji/work/test/n-body-test.php(126)<127>
101 <main> /home/sji/work/test/n-body-test.php(187)<34>
98 NBodySystem::advance /home/sji/work/test/n-body-test.php(126)<77>
92 <main> /home/sji/work/test/n-body-test.php(188)<116>
1 printf <internal>(-1)<-1>
1 <main> /home/sji/work/test/n-body-test.php(190)<129>
1 <main> /home/sji/work/test/n-body-test.php(190)<112>
According to https://github.com/php/php-src/blob/PHP-7.4.8/Zend/zend_vm_opcodes.h , frequently appeard opcodes are
12: ZEND_POW
28: ZEND_ASSIGN_OBJ_OP
82: ZEND_FETCH_OBJ_R
3: ZEND_MUL
78: ZEND_FE_FETCH_R
22: ZEND_ASSIGN
60: ZEND_DO_FCALL
ZEND_DO_FCALL is the line calls NBodySystem::advance, so it can be ignored to see the result.
By just using PHP 8.0 beta and JIT, the execution time has been reduced to 1/4 on my machine.
Then replacing
X ** 2
toX * X
, and move fetching properties of$referenceBody
to outside of the most inner loop, the execution time has been reduced to 1/2 from it!