Performance¶
A fair question about any math library is whether it's fast enough to run inside a render loop, where you might build dozens of matrices and transform thousands of vectors every single frame. The good news: because these classes are implemented in C, with each vector component stored as a plain float, the overhead of using them is minimal, at least by PHP standards.
You don't need to take that on faith. Below are benchmarks comparing PHP-GLFW's C-backed classes against an equivalent pure-PHP implementation.
Note
Benchmarks are always a little controversial and depend heavily on the use case. The pure-PHP implementation used here isn't claimed to be perfectly optimized, but then, neither is the C one. Treat these as a rough sense of the gap, not gospel.
Vector math¶
This is the code under test, a couple of Vec4 multiplications and a normalize:
$v1 = new Vec4(1.0, 2.0, 3.0, 4.0);
$v2 = new Vec4(5.0, 6.0, 7.0, 8.0);
$v3 = $v1 * $v2 * $v1;
$v3->normalize();
The pure-PHP comparison uses a userland Vec4 implementation, Vec4.php, doing the same work through static methods:
$v1 = new Vec4PHP(1.0, 2.0, 3.0, 4.0);
$v2 = new Vec4PHP(5.0, 6.0, 7.0, 8.0);
$v3 = Vec4PHP::_multiplyVec4($v1, $v2);
$v3 = Vec4PHP::_multiplyVec4($v3, $v1);
$v3 = Vec4PHP::_normalize($v3);
The benchmarks were run with phpbench: each case runs 10,000 times, iterating the code above 1,000 times, for 10,000,000 iterations in total.
Average iteration times by variant
1.8ms │ █
1.5ms │ █
1.3ms │ █
1.1ms │ █
881.0μs │ █
660.7μs │ █
440.5μs │ █ █
220.2μs │ █ █
└─────
1 2
+-----------------------+---------+-----------+--------+---------+
| subject | memory | mode | rstdev | stdev |
+-----------------------+---------+-----------+--------+---------+
| benchVec4PHPMulGL () | 1.615mb | 420.948μs | ±0.00% | 0.000μs |
| benchVec4PHPMulPHP () | 1.615mb | 1.762ms | ±0.00% | 0.000μs |
+-----------------------+---------+-----------+--------+---------+
For this simple test the GL functions come out roughly 400% faster than the PHP implementation.
Matrix math¶
The more complex the operation, the wider the gap grows, because PHP's per-call overhead becomes the bottleneck. Here's a matrix multiply followed by an inverse (GL\Math\Mat4):
Against the pure-PHP Mat4, Mat4.php:
As expected, the difference is even more pronounced: PHP-GLFW is around 1,500% faster here. Again, not an entirely fair comparison, but a telling one.
3.8ms │ █
3.4ms │ █
2.9ms │ █
2.4ms │ ▆ █
1.9ms │ █ █
1.4ms │ █ █
961.7μs │ █ █
480.9μs │ ▄ █ ▅ █
└─────────
1 2 3 4
+-----------------------+---------+-----------+--------+---------+
| subject | memory | mode | rstdev | stdev |
+-----------------------+---------+-----------+--------+---------+
| benchMat4PHPMulGL () | 1.615mb | 215.356μs | ±0.00% | 0.000μs |
| benchMat4PHPMulPHP () | 1.615mb | 2.240ms | ±0.00% | 0.000μs |
| benchMat4PHPInvGL () | 1.615mb | 249.179μs | ±0.00% | 0.000μs |
| benchMat4PHPInvPHP () | 1.615mb | 3.847ms | ±0.00% | 0.000μs |
+-----------------------+---------+-----------+--------+---------+
The takeaway is simple: build your matrices and transform your vectors freely inside the render loop. The math library is designed to keep up.