2010-05-11 15 views
7

Büyük bellek içi dizeleri işlemek için PHP'de bir çözümleyici yazıyorum, bu yüzden bu önemli bir sorundur. (lütfen, lütfen "erken optimize etmeyin" lütfen beni alevleyin, lütfen)PHP'nin substr ne kadar verimli?

substr işlevi nasıl çalışır? Dize verisinin hafızada ikinci bir kopyasını mı yoksa asıl referansı mı? Bir döngüde örneğin $str = substr($str, 1);'u arama konusunda endişelenmeli miyim?

+2

Ben atama katil değil substr olacağını düşünürdüm. – CaffGeek

cevap

3

Daha fazla Çad'ın yorumu için, kodunuz her iki dizenin de (tam ve bir tam eksi-ilk karakter) aynı anda bellekte olmasını gerektiriyordu (ancak, Chad'in belirttiği ödev nedeniyle değil). Bkz: gibi

$string = str_repeat('x', 1048576); 
printf("MEM: %d\nPEAK: %d\n", memory_get_usage(), memory_get_peak_usage()); 

substr($string, 1); 
printf("MEM: %d\nPEAK: %d :-(\n", memory_get_usage(), memory_get_peak_usage()); 

$string = substr($string, 1); 
printf("MEM: %d\nPEAK: %d :-(\n", memory_get_usage(), memory_get_peak_usage()); 

Çıkışlar şey (bellek değerleri bayt gösterilmiştir):

MEM: 1093256 
PEAK: 1093488 
MEM: 1093280 
PEAK: 2142116 :-(
MEM: 1093276 
PEAK: 2142116 :-(
1

Evet, her döngüde dizenin yeni kopyaları üretileceğinden, döngü içinde herhangi bir dize işlemi yapmaya dikkat etmelisiniz.

+0

Ben bir php adamı değilim, bu yüzden basitçe söyleyebilirsiniz. Java'da, sadece aynı değişmez char dizisine yeni bir referans oluşturur. Bu yüzden yeni bir String nesnesi oluştururken, alttaki karakter dizisinin daha fazla kopyasını almaz. Sadece ofsetlerin farklı olacağını ilan eder. Php aslında char dizisinin yeni bir kopyasını oluşturur mu? Veya sadece aynı char dizisine başvurunuz. – corsiKa

4

Verimliliği gerçekten arıyorsanız, bir işaretçiyi - yani dizini - dizginizle tutmalısınız. Birçok dize işlevi, çalışmaya başlamak için bir ofseti kabul eder (strpos()'un üçüncü parametresi gibi). Normalde bu işlevselliği sarmak için bir nesne yazmanızı öneririm, ancak bunu çok fazla kullanmayı düşünüyorsanız, bu durum performans darboğazına neden olabilir.

while ($whatever) { 
    $pos = strpos($string, $myToken, $startIndex); 
    # do something using $pos 
    $startIndex = $pos; 
} 

İsterseniz, bu dize işlemlerini yapar kendi sarmalayıcı sınıf yazabilir ve bir hız etkisi olup olmadığını görmek:

class _String { 
    private $string; 
    private $startIndex; 
    private $length; 
    public function __construct($string) { 
     $this->string = $string; 
     $this->startIndex = 0; 
     $this->length = strlen($string); 
    } 
    public function substr($from, $length = NULL) { 
     $this->startIndex = $from; 
     if ($length !== NULL) { 
      $this->endIndex = $from + $length; 
     } 
    } 
    # other functions you might use 
    # ... 
} 
İşte bir ben (OO olmadan) ne anlama geldiğini örneğidir
+0

Normal Java dizeleri bunları otomatik olarak yapar. Neden PHP değil? – Pacerier