欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP關(guān)于foreach復(fù)制知識(shí)點(diǎn)總結(jié)

 更新時(shí)間:2019年01月28日 14:48:52   投稿:laozhang  
在本篇文章里小編給大家分享了關(guān)于PHP關(guān)于foreach復(fù)制知識(shí)點(diǎn)總結(jié),有興趣的朋友們學(xué)習(xí)下。

PHP的foreach是一個(gè)非常整潔和切中要害的語(yǔ)言結(jié)構(gòu)。仍然有些人不喜歡使用它,因?yàn)樗麄冋J(rèn)為它是緩慢的。一個(gè)通常命名的原因是foreach復(fù)制它迭代的數(shù)組。

因此,一些人建議寫(xiě):

$keys = array_keys($array);
$size = count($array);
for ($i = 0; $i < $size; $i++) {
  $key  = $keys[$i];
  $value = $array[$key];
 
  // ...
}

而不是更直觀(guān)和直接:

foreach ($array as $key => $value) {
  // ...
}

這里有兩個(gè)問(wèn)題:

Microoptimization是不好的。通常,它只會(huì)浪費(fèi)您的時(shí)間,不會(huì)帶來(lái)任何可度量的性能改進(jìn)。

foreach的復(fù)制行為比大多數(shù)人認(rèn)為的要復(fù)雜一些。通常情況下,“優(yōu)化”的版本會(huì)比原始版本慢。

foreach什么時(shí)候復(fù)制?

foreach是否復(fù)制數(shù)組以及復(fù)制的數(shù)量取決于三件事:

是否引用了迭代數(shù)組、它的refcount有多高以及迭代是否通過(guò)引用完成。

沒(méi)有引用,refcount == 1

在下面的代碼中,$array沒(méi)有被引用,并且refcount為1。在這種情況下,foreach不會(huì)復(fù)制數(shù)組(證明)——這與流行的觀(guān)點(diǎn)相反,即foreach總是復(fù)制沒(méi)有引用的迭代數(shù)組。

test();
function test() {
  $array = range(0, 100000);
  foreach ($array as $key => $value) {
    // ...
  }
}

原因很簡(jiǎn)單:為什么要這樣做?foreach修改$array的唯一地方是它是內(nèi)部數(shù)組指針。這是預(yù)期的行為,因此不需要預(yù)防。

未引用,refcount > 1

下面的代碼看起來(lái)非常類(lèi)似于前面的代碼。唯一的區(qū)別是數(shù)組現(xiàn)在作為參數(shù)傳遞。這似乎是一個(gè)無(wú)關(guān)緊要的區(qū)別,但它確實(shí)改變了foreach的行為:

它現(xiàn)在將復(fù)制數(shù)組結(jié)構(gòu),而不是值(證明;如果你想知道這只是復(fù)制的結(jié)構(gòu),比較一下這個(gè)和那個(gè)腳本。第一個(gè)只復(fù)制結(jié)構(gòu),第二個(gè)兩個(gè)都復(fù)制)。

$array = range(0, 100000);
test($array);
function test($array) {
  foreach ($array as $key => $value) {
    // ...
  }
}

乍一看這可能有點(diǎn)奇怪:

為什么當(dāng)數(shù)組通過(guò)參數(shù)傳遞時(shí),它會(huì)復(fù)制,但如果它是在函數(shù)中定義的,它就不會(huì)復(fù)制了?原因是數(shù)組zval現(xiàn)在在多個(gè)變量之間共享:函數(shù)外部的$array變量和函數(shù)內(nèi)部的$array變量。如果foreach在不復(fù)制數(shù)組結(jié)構(gòu)的情況下迭代數(shù)組,那么它不僅會(huì)改變函數(shù)中$array變量的數(shù)組指針,還會(huì)改變函數(shù)外$array變量的指針。因此foreach需要復(fù)制數(shù)組結(jié)構(gòu)(即散列表)。另一方面,這些值仍然可以共享zvals,因此不需要復(fù)制。

引用

下一種情況與前一種情況非常相似。唯一的區(qū)別是數(shù)組是通過(guò)引用傳遞的。在這種情況下,數(shù)組將不會(huì)被復(fù)制(證明)。

$array = range(0, 100000);
test($array);
function test(&$array) {
  foreach ($array as $key => $value) {
    // ...
  }
}

在這種情況下,相同的推理適用于前一種情況:外部$數(shù)組和內(nèi)部$數(shù)組共享zvals。不同的是,它們現(xiàn)在是引用(isref == 1),因此在這種情況下,對(duì)內(nèi)部數(shù)組的任何更改都將對(duì)外部數(shù)組進(jìn)行。所以如果內(nèi)部數(shù)組的數(shù)組指針改變了,外部數(shù)組的數(shù)組指針也應(yīng)該改變。這就是foreach不需要復(fù)制的原因。

迭代通過(guò)引用

上面的例子都是按值迭代的。對(duì)于引用迭代,應(yīng)用相同的規(guī)則,但是附加值引用更改數(shù)組值的復(fù)制行為(關(guān)于結(jié)構(gòu)復(fù)制的行為保持不變)。

情況“未引用,refcount == 1”沒(méi)有改變。引用迭代意味著如果$值有任何變化,我們想要改變?cè)紨?shù)組,這樣數(shù)組就不會(huì)被復(fù)制(證明)。

“被引用”的情況也保持不變,在這種情況下,對(duì)$value的更改應(yīng)該會(huì)更改引用迭代數(shù)組的所有變量(證明)。

只有“未引用,refcount > 1”的情況發(fā)生了變化,因?yàn)楝F(xiàn)在需要復(fù)制數(shù)組結(jié)構(gòu)及其值。數(shù)組結(jié)構(gòu),因?yàn)榉駝t函數(shù)外部的$array變量的數(shù)組指針會(huì)改變,而對(duì)$value的改變也會(huì)改變外部的$array值(證明)。

總結(jié)

當(dāng)且僅當(dāng)?shù)鷶?shù)組未被引用且具有refcount > 1時(shí),foreach將復(fù)制數(shù)組結(jié)構(gòu)

foreach還將復(fù)制數(shù)組值,前提是且僅當(dāng)上一個(gè)點(diǎn)應(yīng)用并且迭代是通過(guò)引用完成時(shí)

相關(guān)文章

最新評(píng)論