2

2つの変数があり、両方をに等しくしたいとしnullます。(より現実的には、大量のnullsを含む配列について考えていますが、質問には「2つの変数」のシナリオで十分です。)明らかに、これは複数の方法で実行できます。私はこれを行うことができます(方法1):

$a = null;
$b = $a;

私の理解では、これの結果は、シンボルテーブルの2つのエントリによって示される1つのzvalがあるということです:'a''b'。しかし、代わりにこれを行うかもしれません(方法2):

$a = null;
$b = null;

素朴なことに、これにより2つの異なるzvalが生成され、それぞれがシンボルテーブルの1つのエントリによってポイントされることが期待されます。

このことから、大きな配列が必要で、配列の多くの要素がである場合は、値を使用して変数を作成し、の要素を書き込むnull方が(zval / memoryの使用に関して)より効率的であるということになりますか? ?を使用して割り当てることによる配列$master_nullnullnull$master_null

4

3 に答える 3

2

このスクリプトについて考えてみましょう。

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

これは私のマシンで出力されます:21687696、つまり21MBの使用済みメモリです。一方、これを使用すると:

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

出力:13686832、つまり13MB。この情報に基づいて、メモリ使用量が懸念される限り、実際には「マスターヌル」変数を使用する方が実際には優れていると推測できます。ただし、それでも配列内のすべての項目が必要であり、HashTable(配列の内部表現)のすべてのエントリもある程度のメモリを必要とします。

zvalsと参照をさらに深く掘り下げたい場合は、関数を使用することをお勧めしますdebug_zval_dump。これを使用すると、どの変数が同じ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を共有します。この関数についてはご存知だと思いますが、そうでない場合は、 http:debug_zval_dump //php.net/manual/en/function.debug-zval-dump.phpでrefcountの説明を注意深くお読みください。

また、私の投稿の最後に、この情報はPHPの内部に関する知識を深めるのに役立つかもしれないと言いたいのですが、最適化を行うことはまったく役に立たないと思います。主な理由は、そのようなマイクロ最適化よりも、スクリプトの最適化を開始するのにはるかに適した場所があるためです。また、これは仕様の一部ではありませんが、PHPの作成者は将来この動作を変更する可能性があります(たとえば、将来のバージョンでは、すべてのNULL変数が同じzvalを共有する可能性があります)。

于 2012-04-21T16:08:17.760 に答える
1

私が理解していることから、PHPzvalコンテナーには参照カウントロジックがあります。したがって、私の印象は、参照、つまり&$ master_nullを使用してすべてのNULL値を初期化する場合、スペースを節約できると思います。つまり、配列のすべてのNULL項目がzvalコンテナへの同じ参照を指します。

次に例を示します。

# php -r '$var1 = NULL; $var2 = $var1; $var3 = $var1; debug_zval_dump(&$var1); debug_zval_dump(&$var2); debug_zval_dump(&$var3);'
&NULL refcount(2)
&NULL refcount(2)
&NULL refcount(2)

PHPの参照カウントの基礎について詳しくは、次を参照してください。

このリンクから読む価値のあるものは次のとおりです。

PHP is smart enough not to copy the actual variable container
when it is not necessary. Variable containers get destroyed 
when the "refcount" reaches zero. The "refcount" gets decreased by 
one when any symbol linked to the variable container leaves the 
scope (e.g. when the function ends) or when unset() is called on a symbol.

したがって、&$ master_nullを使用するたびに、「refcount」が増加し、「refcount」がゼロに達すると、変数コンテナーがメモリーから削除されます。


上記のコメントの例から、メモリ使用量は次のようになります。

# php -r '$arr = array(); for ($i = 0; $i < 100000; $i++) $arr[] = null; echo memory_get_usage() . "\n";'
11248372
# php -r '$master_null = null; $arr = array(); for ($i = 0; $i < 100000; $i++) $arr[] = &$master_null; echo memory_get_usage() . "\n";'
6848488
# php -r '$master_null = null; $arr = array(); for ($i = 0; $i < 100000; $i++) $arr[] = $master_null; echo memory_get_usage() . "\n";'
6848468
于 2012-04-21T16:07:46.980 に答える
0

達成できるのは、という追加の変数があるということだけではありません$master_null。それらはすべてnullを指します。それらをそれぞれポイントにすること$master_nullは同じことです。

于 2012-04-21T15:33:42.660 に答える