PHP işlevi verimleri

5 Cevap php

PHP belirli bir işlevi yürütmek için gereken ne kadar "iş" bir tablo var mı? Ben bir compsci önemli değilim, bu yüzden ya da böyle bir şey "Ah evet, dizeleri tamsayılar daha çalışmak için daha uzun sürer" olduğunu bilmek belki de resmi arka plan yok. Bir programda tüm adımları / hatları eşit yaratılmıştır? Ben sadece hatta nerede bu araştırma başlatmak için bilmiyorum.

Ben şu anda benim cevap çalışacak çok eminim bazı Project Euler soruları yapıyorum, ama benim istekleri ile bir dakika benim yerel Apache sunucusunu aşımından ediyorum (ve PE tüm sorunların <çözülebileceğini söyledi 1 dakika). Ben bu yüzden PHP hakkında daha fazla bilmek, nasıl / nereden optimize başlatmak için bilmiyorum ve nasıl kullandığı bellek yararlı olacaktır. Bu değer ne için, burada benim kod question 206:

<?php
$start = time();
for ($i=1010374999; $i < 1421374999; $i++) { 
$a = number_format(pow($i,2),0,".","");
$c = preg_split('//', $a, -1, PREG_SPLIT_NO_EMPTY);
if ($c[0]==1) {
	if ($c[2]==2) {
		if ($c[4]==3) {
			if ($c[6]==4) {
				if ($c[8]==5) {
					if ($c[10]==6) {
						if ($c[12]==7) {
							if ($c[14]==8) {
								if ($c[16]==9) {
									if ($c[18]==0) {
										echo $i;
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
}
$end = time();
$elapsed = ($end-$start);
echo "<br />The time to calculate was $elapsed seconds";
?>

Bu optimizasyonu hakkında bir wiki soru ise, sadece bana bildirin ve ben hareket edeceğiz. Yine bir cevap aramıyorum, sadece (üstünkörü ipuçları reddetti dışarı düz olmaz, ancak ben sorun kurmak daha şık matematiksel yolu muhtemelen vardır fark) benim kodlama verimli olmanın öğrenmek nerede hakkında yardım

5 Cevap

Yürütme zamanı girişine bağlı olarak çılgınca değişir beri her PHP işlevi yürütmek için ne kadar sürer sana anlatacak böyle bir tablo yok.

Kod ne yapıyor bir göz atın. Sen 411000000 kez çalıştırmak için gidiyor bir döngü oluşturduk. Kodu, 60 saniyeden daha az (bir dakika) tamamlamak için size döngünün her gezi varsayıyoruz sorunu çözmek için (yaklaşık) 0,000000145 saniyeden az sürer ihtiyacı göz önüne alındığında. Bu mantıksız ve "doğru" fonksiyonunu kullanarak hiçbir miktarı çağrı çözecektir. Orada nothing ile döngü deneyin

for ($i=1010374999; $i < 1421374999; $i++) { 

}

Eğer bilim kurgu bilgisayarlara erişimi yoksa, bu muhtemelen en az 60 saniye içinde yürütme tamamlamak için gitmiyor. Yani bu yaklaşım hiç çalışmaz biliyorum.

Bu sorun için bir kaba kuvvet çözüm bilinmektedir. Proje Euler nokta sorunlar hakkında, bir matematik ve bakış programlama açısından, hem de yaratıcı düşünme elde etmektir. Eğer bu döngü almak gerekir geziler reduce numarasına istiyorum. Bariz çözüm burada cevap olmayacak.

Ben bu şeyleri noktasında bunun üzerinden yol düşünmek ve daha iyi bir algoritma programcı olmak için, çünkü, size çözüm söylemek istemiyorum. Sorunu incelemek, bu kısıtlamaları düşünmek, ve size kontrol etmek gerekiyordu sayıların toplam sayısını azaltmak yollarını düşünmek.

Kodunuz için yürütme zamanlarda bir göz için iyi bir araç olduğunu xdebug: http://xdebug.org/docs/profiler

Bu çıkış için komut dosyası işlev çağrıları ve yürütme kez tam bir dökümünü yapılandırılabilir kurulabilir bir PHP uzantısı. Bunu kullanarak, bazı farklı yaklaşımlar yürütmek ve denemek için uzun alıyor kodunuzda görmek mümkün olacak.

EDIT: şimdi ben aslında koduna bakıyorum ki, siz 400 milyon + regex çağrı bitiyor! Ben proje Euler hakkında hiçbir şey bilmiyorum, ama ben bir sabit zaman inanarak bu kod emtia donanım üzerinde bir dakika altında istediğinde edilebilir var.

preg_split bir regex kullanarak çünkü yavaş olması muhtemeldir. Bu satırı yapmak için daha iyi bir yolu var mı?

İpucu: Böyle bir dize karakter erişebilirsiniz:

$str = 'This is a test.';
echo $str[0];

Öncelikle, burada hata ayıklama çıkışı ile, senin fonksiyonun biraz daha temiz bir versiyonu

<?php
$start = time();
$min = (int)floor(sqrt(1020304050607080900));
$max = (int)ceil(sqrt(1929394959697989990));

for ($i=$min; $i < $max; $i++) {
$c = $i * $i;
echo $i, ' => ', $c, "\n";
if ($c[0]==1
    && $c[2]==2
        && $c[4]==3
        && $c[6]==4
        && $c[8]==5
        && $c[10]==6
        && $c[12]==7
        && $c[14]==8
        && $c[16]==9
        && $c[18]==0)
  {
    echo $i;
        break;
  }
}
$end = time();
$elapsed = ($end-$start);
echo "<br />The time to calculate was $elapsed seconds";

Ve burada çıkışının ilk 10 satır var:

1010101010 => 1020304050403020100
1010101011 => 1020304052423222121
1010101012 => 1020304054443424144
1010101013 => 1020304056463626169
1010101014 => 1020304058483828196
1010101015 => 1020304060504030225
1010101016 => 1020304062524232256
1010101017 => 1020304064544434289
1010101018 => 1020304066564636324
1010101019 => 1020304068584838361

Bu algoritma olası bir optimizasyon ilham oughta gibi bu, orada görünüyor. Biz 5 gereken bir konumda bir 6 var - biz 6 girişi (1020304060504030225) itibariyle, yakın bile değiliz unutmayın!

Biz geri o konumda bir 5 var bir noktada oluncaya kadar aslında, bir sonraki girişlerin çoğunun, değersiz olacaktır. Neden Aradan değerleri caluclating rahatsız? Biz haneli biz böyle bir anda yineleme onlarca atlayarak tutabilir ise 5 ... yine bizim çalışma süresi% 90 üzerinde de tasarruf edeceğiz haline nerede nasıl, biz, 1010101060 atlayabilirsiniz gerektiğini anlamaya eğer !

Bu hiç de pratik bir yaklaşım (aslında, ben öyle değil oldukça emin değilim) olmayabilir, ama bu düşünme olmalıdır yol olduğunu unutmayın. Eğer yürütmek iterasyon sayısını azaltmak için matematiksel ne hileler kullanabilirim?