我阅读了一些关于 PHP 引用以及它们如何影响性能的文章。
我也看到了一些测试,证明是一样的。
这些资源中的大多数都声称这是因为引用禁用了写时复制。
但我不明白为什么会出现问题? PHP 不会复制数组,例如,仅仅因为您通过引用传递了它。
function foo(&$var) {
$var->test = 'bar';
xdebug_debug_zval('var');
}
$data = new stdclass;
foo($data);
和我收到的结果
(refcount=3, is_ref=1),
object(stdClass)[1]
public 'test' => (refcount=1, is_ref=0),string 'bar' (length=3)
这表明没有进行复制,并且该函数仍在使用相同的变量(处理实际变量而不是复制)。
我错过了什么,为什么会出现性能损失?
我尝试使用 3v4l.com 网站进行基准测试。
您可以在这里找到资源:https://3v4l.org/NqHlZ
以下是我针对当前最新 PHP 版本获得的结果,迭代次数为 10k:
5.5.33 的输出
Avergages:
- Object through reference, explicitly: 2.5538682937622E-6
- Object through reference, implicitly: 1.8869638442993E-6
- Array through copy-on-write: 1.9102573394775E-6
- Array through reference: 9.3061923980713E-7
5.6.19 的输出
Avergages:
- Object through reference, explicitly: 2.2409210205078E-6
- Object through reference, implicitly: 1.7436265945435E-6
- Array through copy-on-write: 1.1391639709473E-6
- Array through reference: 8.7485313415527E-7
7.0.4 的输出
Avergages:
- Object through reference, explicitly: 4.6207904815674E-7
- Object through reference, implicitly: 3.687858581543E-7
- Array through copy-on-write: 4.0757656097412E-7
- Array through reference: 3.0455589294434E-7
因此,对于所有最新的 PHP 版本,通过引用传递而不是进行写时复制没有性能问题。
“显式通过引用传递对象”部分实际上不是一种编码方式,因为所有对象都是通过引用传递的,无论是否使用“&”符号。也许当变量是对象时使用此符号通过引用显式传递变量导致到达包含另一个包含数据的内存地址的内存地址,这可以解释为什么它需要更长的时间。