Büyük performans düşüş ilişkisel PHP dizi nesne erişirken

2 Cevap php

Ben basit bir atamayla (29.x saniye 0.8 ~ 0.9 saniye zamanı artış) neden olduğu bir (komut satırı) PHP komut dosyası, büyük bir performans düşüklüğünü görüyorum.

Komut ilk MySQL veritabanı çok veri getirir ve farklı özel sınıfların nesneleri oluşturur. Bu getiriliyor sonra edici döngüsü onun özelliklerinden biri olarak ilişkilendirilebilir bir dizi (100 girişleri etrafında boyut) vardır, her biri yaklaşık 3.500 Sample nesneler, bir dizi (php şimdi RAM yaklaşık 500 MB kullanır). Bu dizi iki özellikleri ile küçük nesneleri Value nesneleri tutan ve anahtarlar 6'000 daha küçük tamsayılardır. Bu benim sorunun tökezledi nerede, bu kodu görürsünüz:

foreach ($samples as $id => $s) {    # $s is now a 'Sample' object
    $values = $s->values();          # $values is an array of 'Value' objects

    if (isset($values[$match_id])) {
        $num_tested++;
        # $val = $values[$match_id];     # contains a 'Value' object
        # $val = &$values[...]; -> the loop never ends (!)
    }
}

Note that commented line. If I run the code as it appears here, this block runs for about 0.8 to 0.9 seconds. If I uncomment this single line, the block runs for almost 30 seconds. I found that if the array is non-associative (it only contains consecutive keys from 0 to about 100) the runtime only increases to 1.8 ~ 1.9 seconds.
It seems that this happens because of the non-consecutive array keys I use, but then again why does the performance not already decline by calling isset($values[$match_id])? Is there a workaround for this or do I have to live with that?

Running PHP 5.3.0, Zend Engine v2.3.0, Mac OS X Server 10.6.2

2 Cevap

Eğer 5.3 çalıştırıyorsanız, yeni Spl veri yapılarına bakmak. Onlar gösterildiği gibi can, büyük koleksiyonları için önemli bir performans artışı elde here ve here. Bunun dışında, bu soruna neden olabilir ne anlatmak biraz zor. Eğer xdebug kullanmak için ya Zend_Debugger daha fazla bilgi almak için denediniz mi?

$val =& $values[$match_id] (referans atama) ile $val = $values[$match_id] (kopya göre atama) değiştirmeyi deneyin ve daha iyi gerçekleştirir olmadığını görmek.