PHP null 和写时复制 [英] PHP null and copy-on-write

查看:45
本文介绍了PHP null 和写时复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我想要两个变量,并且它们都等于 null.(更现实地说,我正在考虑一个包含大量 null 的数组,但两个变量"场景足以解决这个问题.)显然,我可以在多个中做到这一点办法.我可以这样做(方法 1):

Suppose I want to have two variables and have them both equal to null. (More realistically, I am thinking about an array that contains a large amount of nulls, but the "two variables" scenario is sufficient for the question.) Obviously, I can do this in more than one way. I can do this (method 1):

$a = null;
$b = $a;

据我所知,这样做的结果是符号表中的两个条目指向一个 zval:'a''b'.但也可以这样做(方法 2):

By my understanding, the result of this is that there is one zval that is pointed to by two entries in the symbol table: 'a' and 'b'. But alternatively one might do this (method 2):

$a = null;
$b = null;

天真地认为这会导致两个不同的 zval,每个 zval 都由符号表中的一个条目指向.

Naively one would expect that this should result in two different zvals, each pointed to by one entry in the symbol table.

是否由此得出,如果您想要一个大数组,并且该数组的许多元素将为 null,那么创建一个更有效(就 zval/内存使用而言)$master_null 变量的值为 null,然后使用 $master_null 赋值写入数组的 null 元素?

Does it follow from this that if you want to have a large array, and many elements of the array will be null, it's more efficient (in terms of zval/memory use) to create a $master_null variable with the value null, and then write the null elements of the array by assigning using $master_null?

推荐答案

考虑这个脚本:

$arr = array();
for ($i = 0; $i < 100000; $i++) $arr[] = null;
echo memory_get_usage() . "\n";

在我的机器上输出:21687696,即 21 MB 的已用内存.另一方面使用这个:

which on my machine outputs: 21687696, that is 21 MB of used memory. On the other hand using this:

$master_null = null;
$arr = array();
for ($i = 0; $i < 100000; $i++) $arr[] = $master_null;
echo memory_get_usage() . "\n";

输出:13686832,即 13 MB.根据这些信息,您可以假设就内存使用而言是您关心的问题,实际上最好使用master null"变量.但是,您仍然需要拥有数组中的所有项,并且 HashTable 中的每个条目(数组的内部表示)也需要一些内存.

outputs: 13686832, which is 13 MB. Based on this information, you can assume that at far as memory usage is your concern, it is actually better to indeed use the "master null" variable. However you still need to have all the items in the array, and every entry in a HashTable (internal representation of arrays) takes also some memory.

如果你想深入挖掘 zvals 和引用,我建议使用函数 debug_zval_dump.使用它,你可以看到,哪些变量共享同一个 zval:

If you want to dig deeper in the zvals and references, I suggest using the function debug_zval_dump. Using it, you can see, which variables share the same zval:

$a = $b = $c = $d = "abc";
debug_zval_dump($a);
$x = $y = $z = $w = null; 
debug_zval_dump($x);
$q = null;
debug_zval_dump($q);

输出:

string(3) "abc" refcount(5)
NULL refcount(5)
NULL refcount(2)

这意味着虽然变量 $x 和 $q 都是 NULL,但它们不是同一个 zval.但是 $x 和 $y 共享同一个 zval,因为它们是相互分配的.我相信您知道函数 debug_zval_dump,但如果不知道,请确保您仔细阅读 http://php.net/manual/en/function.debug-zval-dump.php.

And this implies that although variables $x and $q are both NULL, they are not the same zval. But $x and $y share the same zval, because they are assigned to each other. I believe you know of the function debug_zval_dump, but if not, make sure you carefully read the refcount explanation at http://php.net/manual/en/function.debug-zval-dump.php.

在我的帖子最后,我想说这些信息可能对更好地了解 PHP 内部结构很有用,我认为做任何优化都是无用的.主要是因为有比这种微优化更好的地方开始优化脚本.此外,虽然这不是规范的一部分,但 PHP 作者可能会在未来改变这种行为(例如,所有 NULL 变量在未来的某个版本中可以共享相同的 zval).

Also at the end of my post, I want to say that this information might be useful for a better knowledge of PHP internals, I think it is quite useless to do any optimizations. Mostly because there are much better places to start optimizing scripts than such micro-optimizations. Also while this is not part of the specification, PHP authors might change this behaviour in the future (e.g. all NULL variables could share the same zval in some future version).

这篇关于PHP null 和写时复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆