ちょっとした洞察 (オンラインの風雪コーナーおよび関連情報を参照):
引用とコピーの違い:
参照が実際には $a = 1; $b = $a であることは誰もが知っています。$a または $b を変更しても相手には影響しません。参照はアドレスで値を渡すことです: $a = 1; $b = &$a; 他の値を変更すると変更されます。
ただし、最後に理由を追加してください。なぜこれがこのようになるのですか?
PHP の 2 つのメカニズムはコピーオンライトとチェンジオンライトであることを誰もが理解する必要があります。
コピーオンライト: コピーオンライトは変数のコピーに適用されます。たとえば、上記の例では、$a = 1; $a 変数がシンボル テーブルに格納され、値 "1" が zval に格納されます。
がphpに保存されていることを意味します変数、各変数名はシンボル テーブルに格納され、各シンボルは zval に対応し、変数値、変数タイプなどを格納するコンテナとみなすことができます。
$a = 1;$b = $a; メモリ内に 2 つの「1」があると考える人もいるかもしれませんが、実際には、$a と $b の両方が格納されている zval コンテナを指しています。 1. $a と $b のそれぞれに
を指す線があるのと鮮明に比較できます。Zval、zvalにはrefcountと呼ばれるパラメータがあり、それ自体を指す行の数をカウントします。変数がコピーされると、refcount が 1 ずつ増加します。つまり、 $a = 1; この時点では
を保存します。1 が配置されている zval 構造体の refcount 値は 2 です。 php には、debug_zval_dump($v); という関数があります。これは、$a が
で始まるため、カウントが 3 の場合です。値形式は debug_zval_dump に渡されるため、出力される値は 3 です。
次に、変数の refcount を 1 つ減らす問題を説明します。つまり、refcount 値が 0 になると、変数値によって占有されていたメモリが解放されます。未設定時($b)
1 はメモリ内で解放されませんが、それを指す参照の数は減少します。
前述のメモリ解放はシステム (OS) に解放されない場合があります。変数が生成されると、PHP はその変数を解放するときに、指定されたサイズのメモリを開きます。独自のメモリ領域に解放されます。
あなた自身の記憶領域に。効率の向上に非常に役立ちます。ただし、この指定値を超えると、システムからメモリが申請され、その後システムに解放されます
参照に関しては、zval にマークする別のパラメータ is_ref があります (マークが実際の参照であるかどうか)。この値はデフォルトで 0 になります。たとえば、この時点では $a = 1;$b = &$a; となります。 ); 結果は 1、
refcount = 2、is_ref = 3、
バージョン 5.2.17 のソースコード内の zval の組み合わせは、公式 Web サイトからダウンロードできます
typedef Union _zvalue_value {
long lval; /* 長い値 */
double dval; /* double 値 */
構造体 {
Char *val;
int len;
} str;
HashTable *ht; /* ハッシュ テーブルの値 */
zend_object_value obj;
} zvalue_value;
struct _zval_struct {
/* 可変情報 */
zvalue_value 値; /* 値 */
zend_uint refcount;
zend_uchar タイプ; /* アクティブなタイプ */
zend_uchar is_ref;
};
いくつかのプログラムの実行速度をテストします
テスト環境:
OS:win7
php バージョン 5.2.9
apache2.0
1. 変数の値が空かどうかを判断するには、'!' に変数名を加えたものと、空に変数名を加えて実行時間を比較します (1,000 万回ループ)
if で使用される !$a の実行時間は 2.40036678314s
です。if で empty($a) を使用した場合の実行時間: 2.52875089645s
テストコード:
$start = microtime(true);
$a = '';
for($i=0; $i
if(!$a){// を empty($a) に変更できます
エコー " ";
}
}
$end = microtime(true);
echo "実行時間は:",($end-$start),"s";
?>
2. if-esleを使用した場合と三項演算子を使用した場合の実行時間の比較(1000万回ループ)
if-else を使用すると、実行時間は 2.37516283989s
となります。三項演算子を使用すると、実行時間は 2.14390015602s
となります。三項演算子が実行されると、変数は毎回コピーされます
そうでない場合は、影響はほとんどないので、取り出してみんなと共有しました
テストコード:
$start = microtime(true);
$a = range(1, 1000);
for($i=0; $i
if(isset($a)){
エコー " ";
}その他{
エコー "";
}
}
$end = microtime(true);
echo "実行時間は:",($end-$start),"s";
?>
$start = microtime(true);
$a = range(1, 1000);
for($i=0; $i
isset($a) ? " " : "";
}
$end = microtime(true);
echo "実行時間は:",($end-$start),"s";
?>