PHP başvuruları kullanma

8 Cevap php

I programlama ve tasarımı, sen kararlar için iyi bir neden olması gerektiğini öğrendim çünkü bu soruyu sormak. Ben php öğrenen yaşıyorum ve ben karşısında soruyorum ne im almak için denemek için basit artımları kullanıyorum, burada bir kavşak duyuyorum. Ben referans artıları / eksileri hakkında bir tartışma başlatmak için burada kesinlikle değilim, ama o daha iyi programlama uygulamadır php, gelince:

function increment(&$param) {
      ++$param;
}

vs

function increment($param){
 return ++$param;
}

$param = increment($param);

8 Cevap

İlk olarak, references are not pointers.

Ben onun cevabını @ John tarafından verilen kod çalıştı, ama garip bir sonuç var. Bu microtime() bir dize döndürür çıkıyor. Aritmetik güvenilmez ve hatta bazı çalışır olumsuz sonuçlar aldık. Bir microtime(true) bir float olarak değerini almak için kullanmanız gerekir.

Ben sadece değişkeni arttırırsak, hiçbir işlev çağrısının başka bir test ekledi:

<?php

$param = 1;

$start = microtime(true);

for($i = 1; $i <= 1000000; $i++) {
    $param++;
}

$end = microtime(true);

echo "increment: " . ($end - $start) . "\n";

Benim makinede sonuçları, Macbook 2.4GHz PHP 5.3.2 çalışıyor.

  • referans pass ile işlev çağrısı: 2.14 sec.
  • değerine göre pass ile işlev çağrısı: 2.26 sec.
  • hiçbir işlev çağrısı, sadece çıplak artışı: 0.42 sec.

Yani referans olarak geçen bir% 5.3 performans avantajı var gibi görünüyor, ama tamamen işlev çağrısı kaçınmak için bir% 81 performans avantajı var.

Ben bir tamsayı artan örneği keyfi sanırım, ve OP gerçekten referans olarak geçen genel avantajı soruyor. Ama ben sadece göstermek için bu örneği veriyorum ki the function call alone incurs far more overhead than the method of passing parameters.

Böylece mikro-optimize parametre geçişi için, sen kuruş bilge ve pound aptalca davranıyorsun nasıl karar çalışıyorsanız.

Eğer başvurular kaçınmalısınız başka nedenleri de vardır. Onlar çeşitli algoritmalar kolaylaştırabilirsiniz rağmen, aynı temel veri olması gerekir, iki veya daha fazla veri yapıları manipüle edilir özellikle:

  • Onlar fonksiyonları yan etkileri vardır. Onlar ("işlevlerden herhangi parametrelerini değiştirmek mi? Tamam, nasıl bu değer burada aldın?" Gibi) programı daha tahmin edilemez hale gibi, genel olarak, yan etkileri ile fonksiyonlarını kaçınmalıdır
  • Onlar hata neden olur. Eğer değişkene bir başvuru yaparsanız, size referans kümesinin temel değeri değiştirmek istediğiniz sürece, bunu bir değer atamadan önce onu yoketmek unutmamalısınız. Yeniden kullanmak döngü değişkeni daha sonra referans olarak bir foreach döngü çalıştırmak ve sonra bu sık sık olur.

En iyi uygulama bir ifade yapacak bir işlevi yazmak değildir.

$param++;

tüm ihtiyaç vardır.

Ikinci versiyonu:

function increment($param){
 return $param++;
}

$param = increment($param);

Hiçbir şey yapmaz. artışı () döner $ param. Belki + + $ param ya $ param +1 geliyordu;

Eğer zamanlamaları karşılaştırırsanız, (PHP'nin iyileştirici tamamen işlevini kaldırmak için mümkün olabilir) aynı işlevi karşılaştırdığınız ki ben bilgiçlik taslamak için değil, bu söz ama.

Tanım olarak, (en azından PHP) bir değişkenin değerini artırma değişken dönüşüyor. Bu, bir değer alabilir 1 arttırır ve geri gelmez; yerine bu değeri tutan değişken değiştirir.

Bir $param referansını (PHP gerçekten başına işaretçileri yapmaz) ve post-artan alıyor böylece ilk örneği, gitmek için daha iyi bir yolu olacaktır.

Ben sadece aşağıdaki kod ile bir çift hızlı testler koştu:

<?php

function increment(&$param){
 $param++;
}
$param = 1;

$start = microtime();

for($i = 1; $i <= 1000000; $i++) {
    increment($param);
}

$end = microtime();

echo $end - $start;

?>

Bu kodu aşağıdaki gibi yaklaşık 0,55-0,59 iade değeri 43, tutarlı .42 etrafında döndü,

<?php

function increment($param){
 return $param++;
}
$param = 1;

$start = microtime();

for($i = 1; $i <= 1000000; $i++) {
    $param = increment($param);
}

$end = microtime();

echo $end - $start;

?>

Yani başvuruları daha hızlı olduğunu söyleyebilirim, ama sadece aşırı durumlarda.

Ben örnek biraz soyut olduğunu düşünüyorum.

Işaretçileri kullanarak ama çoğu gerçek dünya durumlarda muhtemelen bir nesneyi değil (en azından PHP5'ta) başvuru gerekmez bu durumda bir int değiştiriyorsunuz ile hiçbir sorun yoktur.

Ben oldukça ne yaptığınızı bağlı olacağını söyleyebilirim. Eğer bellekte bunun fazladan bir kopyasını isteyen olmadan büyük bir veri kümesi üzerinde etkileşim çalışıyorsanız - go ahead, değerine göre (ikinci örnek) geçmektedir. Eğer Hafızayı kaydetmek ve bir nesne üzerinde etkileşim istiyorsanız doğrudan - referans (ilk örnek) geçmek