Yazımda size PHP performansı nasıl atrttırabileceiğinizle ilgili birkaç ipucu vermek istiyorum, böylece ziyaretçileriniz için daha iyi bir deneyim sağlayabileceiniz ve sunucu kaynkalrınınızı (paranızı) boşa harcamayacağınız bir site/fonksiyon kodlayabilirsiniz. İşte madde madde birkaç ipucu:
Bunlar dışında verileri sunucudan istemciye sıkıştırarak gönderirseniz kullanıcılar web sayfasının bilgisayarlarına inmesini fazla beklemeyecektir.
Siz de bildiklerinizi aşağıda paylaşırsanız sevinirim.
önceki yazı Php ile fonksiyonları baglamak |
sonraki yazı Tarayıcı test programı |
peki bunları uygularsak ne kadar performans sağlarız?
hesaplanacak işin yükü fazla olduğunda recursive (özyineleme) yerine iteratif yöntemler tercih edilebilir. çünkü kendini çağıran fonksiyonlar her çağırma işlemi sırasında stack (yığın) oluşturarak dar boğaz yaratırlar. bunun yerine fonksiyon bir kez çağırılıp algoritma bir döngü içine alınırsa söz konusu stack işleminden paçayı sıyırmış oluruz.
Çok güzel bir bildiri olmuş teşekkürler...
Güzel olmuş. Bunlar performans sağlar ama ne kadar? gösterilen özene değecek kadar mı?
@ikuzgun recursive - iteratif olayında %100.000'lere varan performans artışı söz konusu oluyor! (yani bu şu demek, yerine göre recursive yöntemler çalıştığı makineyi kilitleyerek yanıt veremez hale getirebiliyor)
değişkenleri kopyalanması işlemi nasıl oluyor onu almadım ben.
dim degisken
degisken = rsVeritabani("field")
dim degisken2
degisken2 = degisken
böyle bişey olsa gerek
phpde ise
$yes = "yes";
$oke = "oke";
$rep = $oke;
gibi
"nekadar performans artışı sağlar?"
ne kadar kötü yazıldığına ve ne kadar ziyaretçiye cevap vermeye çalıştığına bağlı tabii, denemek gerekir
ama en azından sql sorgularının döngüye sokulması en kötülerinden birisi
bir de 512KB yer kaplayan bir değişkenin 2 tane kopyasının oluşturulduğunu düşünün, 1,5MB oluyor. 20 kişi aynı anda çalıştırsa bunu: 30MB. Oysa sadece 10 MB yer kaplayabilrdi.
Ayrıca sistemin büyüklüğü ile de alakalı, ünlü bir haber sitesininde çalışıyorsanız mesela: mecburen...
mümkün olduğunca dikkat etmek gerekiyor
if/else'in switch/case'ten hızlı olduğunu sanıyordum.
switch casede bir veriyi hafızaya alır ve ona uygun olanı bulup ona göre işlem yaparsınız. İfli ifadelerde ise her koşul için bir kere daha idafeyi çağarırsınız. Bunun için switch daha hızlı çalışır.
Bunlarla alacağınız performans farkı gözardı edilecek kadar...
Döngülerin içine SQL yazmak hariç o çok fark ettirir.
.
Hele değişken kopyalama süpermiş 512KB'lık değişken mi olur?
Bir karakter bir byte olduğuna göre 512KB = 512.000 karakterlik bir değişkenden bahsediyoruz.
Kopyalamayı geç bu kadar büyük değişken kullanmak zaten kendi başına performance killer...
.
Performansla ilgili 1 numaralı kural:
Accelerator kullanın. eAccelerator, APC, Zend Optimizer mıydı neydi hangisi hoşunuza giderse... Bunların elinden geçen bir PHP'deki switch'in printin günümüz bilgisayarlarında hiçbi önemi olmaz.
.
Bu programlamayla alakalı değil belki ama ilginç bir şekilde hala tonla insan kullanmıyor... Ondan sonra da böyle ıncık cıncık şeylerin peşine düşüyor insanlar...
.
.
Daha sonra dikkat etmeniz gerekenler daha çok gereksiz fopen'lar, include'lar, veritabanı bağlantıları, veritabanı optimizasyonu ve nadiren dipsiz döngüler.
.
Performans istiyorsanız DBG, XDebug, Zend Debugger gibisinden bir debugger kurup profiler'ını çalıştırmalısınız. Nerelerde bottleneck'leriniz olduğunu profiler söyler size.
.
Sonraki aşama yine kodlamayla ilgili değil, yüksek yük almaya başladığınız zaman PHP'yi devreden kısmen çıkartmanız gerekli. Kullanabilecekleriniz:
- Byte code optimizerların (eAccelerator vs.) shared memoryleri
- memcached
- squid vb. reverse proxy'ler
- Yazılım tabanlı caching mekanizmaları. Smarty template'larının cache'ini de bu sınıfa sokabiliriz.
.
Bunların mantığı şu: PHP'nin çıktısını hafızaya ya da diske direkt kaydedip verinin güncellenme aralığına ve gelen hit sayısına göre atıyorum en az 3-5sn. boyunca PHP'den değil bu sabit yerden sunmak.
1sn. falan komik geliyor insana ama saniyede 300 - 500 hatta 1000'lerce hit alan boyutta bir servisiniz olduğu zaman 3-5sn.lik cache bile fark ettirebilir.
.
İyice uçuk sistemlerde artık mesela PHP'nin session'ını veritabanında değil memory'de tutmaya başlayabilirsiniz hatta flickr.com session kullanmıyor, session'la ilgili olmazsa olmazları encrypt edip cookie'de tutuyor, direkt oradan alıp zaten memory'de tuttuğu kullanıcı tablosuyla match ediyor falan...
.
Tabii o seviyeye gelmek için önce dikey ve yatay ölçeklendirmenin (horizontal & vertical scalability) dibine vurmak gerekiyor.
.
O yüzden böle ot bokla vakit kaybetmeyin derim ben...
Cal Henderson'ın Building Scalable Web Sites diye bi kitabı var öncelikle onu hatmedin...
4. seçeneğin performansa nasıl bir katkısı var ? Uyumluluk haricinde bir katkısı yok.
Zaten php6'da komple asp style tags desteği kalkıyor.
bana göre php de performans artırmak yerine database de performans yapsanız daha sağlıklı olur nitekim makineniz süperde olsa kullandığınız bir sql cümlesi makinenizi al aşağı yapabiliyor :)
if ve switch yerine göredir bir iki koşul kontol etcekseniz if ile edebilirsiniz ama alt alta yığınla yapcaksanız switch ile yapmanız size kolaylık sağlayacaktır.
for döngüsü olayında ise değişkeni for dışında tanımlayıp fora sokmak daha iyidir lakin bu projenizi kurtarır mı bilemiyorum bunlar mikrosaniyelerdir gözle görülür bişey farkedemezsiniz.
yerine
değişken kopyalama işine gelince kopyalamak daha doğrusu
$ad = $_POST['ad'];
gibi bir tanım okunabilirliği artırsada gereksiz satırlar php nin o satırıda yorumlamasını sağlayacaktır ve tabi zaman haryacaktır ama bu zamanıda siz farketmessiniz.
Nitekim ben şahsen yukarıda verdiğim gibi kod yapısı kullanmıyorum yani deişken kopyalama olayı.
Bunlar dışında söleyebileceğim ilk baştada dediğim gibi php tarafından çok sql arafını düşünün yanlış sql cümleleri ile alaşağı olabilirsiniz.
Ben bazı çalışmalarda görüyorum. Tek satırı basmak için bir ana sql sorgusu, oradan foreach'le gelen sonuca göre içerisinde 2 şer sql sorgusu daha. Eder mi sana 41 sql sorgusu. Bu tarz basit sql sentaxları ile çalışıp kastıran adamlar var. Birleştirin sql sorgularını, mysql olduğundan çok daha güçlüdür. Sadece php bilmekle olmuyor bu iş. Çok akıllıca ve az yoran sql sorguları yazmanız hem sizin kafa karışıklığınızı önler hemde sistemin kafasını karıştırmaz.
Tam kodamanda olması gerektiği gibi bir yazı olmuş,elinize sağlık.
__________________
Sizin yazdığınız 3.Maddedeki count() hadisesi çok önemli , mesela büyük array dizileriyle çalışıyorsanız hayatınızı kurtarır. Büyük array dizilerinde o kısımla işiniz bittiğinde daima unset() kullanarak değişkenleri serbest bırakın.Process bitene kadar geçen 3 milisaniyede bile değişkenlerin boş kalması yüksek trafikli bir sitede hayat kurtarır.
__________________
7.Madde : Bir de genellikle tek tırnak kullanılması makbul deniyor, eğer değişken sonucunu text olarak biçimlendiriyorsak bunu sprintf ile yapmak daha makulmuş.Çünkü çıktıda değişken olduğu ve bu değişkenlerin sayısı belli olduğu için php bu değişkenleri bir daha analiz etmez.
Örnek sprintf kullanımı :
$isim='mayk';
$yas='28';
printf('Merhaba ben %s, %d yasindayim',$isim,$yas);
printf içinde kullandığımız %s , bu değişkenin string olduğunu belirtir. %d ise değişkenin sayı olduğunu belirtir.$yas='yirmisekiz'; yazarsanız bunu orda yazmaz,onun yerine tanimlanamayan degisken olarak 0 yazar.
%s, %d, %e , %x(sadece küçük harf kabul eder) , %X (sadece büyük harf kabul eder)
daha fazla bilgi için php manualindeki şu sayfayı tavsiye ederim.
Yukarıda örnek verdiğim stringi
echo 'Merhaba ben '.$isim.' , '.$yas.' yasindayim';
seklinde de kullanabilirdik ama o zaman php , $isim ve $yas degiskenlerini analiz edip bunların özelliklerinin ne olduğuna karar verecekti. Sprintf de biz phpye bu değişkenlerin ne olduğunu söylediğimiz için,php tekrar bakmaz.
__________________
Şu sitede 50+ sürekli yenileri bulundukça eklenen optimizasyon ipuçları var.Onları da çevirerek yazının veya yazı serisinin devamı olarak kullanabilirsiniz. Sitedeki maddelerin sağ taraflarındaki citationlara tıkladığınızda o maddeye örnek teşkil eden örneğin hangi siteden alındığıda yazmaktadır.
__________________
Bu arada yazdığınız kodun performans ölçümünü yapmak istiyorsanız
http://developers.facebook.com/xhprof/
sayfasındaki , facebook'un geliştirdiği xhprof , çok işinize yarayabilir.
Windows üzerinde çalışan phpciler için de Xdebug iyidir : http://www.xdebug.org/
lonelycavalry tarafından edit: (Xdebug , linuxta ve macte de çalışır.Ancak xhprof'un henüz windows uyumlu binaryleri yok,eğer derlemeyi bilmiyorsanız boşuna indirmeyiniz)
PHP için + performans için hooking de öneriliyor. Apache server yerine Nginx server
Xdebug sadece Windows altında değil Mac Os X ve (kendi denemelerimde) Ubuntu'da da çalışıyor
evet @a.a.b,ben Xdebug windows dışında çalışmaz demedim.Windows kullanıcıları için iyidir dedim. Xdebug eğer source'dan derlenip install edilirse solaris'te bile çalışır. Ben xhprof kullanıyorum, Xdebug'ı sadece evdeki bilgisayarımda(windows) kullanıyorum.
Bunun için windows kullanıcılarına xdebug'ı tavsiye ettim.Linux veya macoscular ne yapacaklarını bilirler zaten.
Yukarıda yazdığım yorumu buna göre editliyorum.
sql optimizasyonunun php optimizasyonundan daha önemli olduğu bir gerçektir.
php tarafında anlatılan işlemleri kod yazmada alışkanlık haline getirebilirsiniz. az kullanıcılı sitelerde gözle görülür bi etki olmasa bile büyük çaplı sitelerde elbet faydası olacaktır.
http://stackoverflow.com/ sitesinde sql optimizasyonu için güzel soru cevaplar mevcut. sql bilen ama ingilizce bilmeyen birisi bile sorgulara bakarak optimizasyon için neler yapabileceğini kavrayabilir.
Umm zumm; 5. madde doğru değil :) ikisinin hız açısından herhangi bir farkı yok.
Umm zumm; 5. madde doğru değil :) ikisinin hız açısından herhangi bir farkı yok.
Çok küçük bir farkı var : switch, case de, ilk ifade zaten hafızaya alınmıştır ve karşılaştırma hafızadaki bu veri ile yapılır.
Fakat if koşul ifadesinde her koşul için birer kere daha hafızaya alınma işlemi yapılır.
Bunların hız bakımından fark yaratacağını zannetmem. Zaten switch case kullanmanız durumunda da break; kullanmak zorunda kalacaksınız. Bu da o anki döngü ya da koşulu bulacak ve o ifadeden çıkmaya çalışacak. Bu bulma işlemindeki harcanacak hafıza ve zaman kaybı aynı duruma denk düşürecektir diye düşünüyorum.
1. echo fonksiyonu print'ten daha hızlıdır. echo çıktıdan başka birşey döndürmezken print 0 ya da 1'i de döndürür.
(performans farkedilemez)
2. $arrPerson[‘isim'] $arrPerson[isim]'den daha hızlıdır.
(ikincisi zaten hatalı)
3. Şunun yerine for($i=0; $i<=count($arrPerson); $i++) {..} şunu kullanın
for($i=0,$total = count($arrPerson); $i<$total; $i++) {..}. İlki her döngüde sayım yapacak fakat ikincisi bu sayımı sadece bir kez yapacak.
(eğer array büyükse, ve döngü içinde değişmeyecekse faydalı)
4. yerine (hız farkı yok, ama ikincisi daha uygun)
5. if/else yerine switch/case kullanmaya çalışın.
(performans farkedilemez)
6. Değişkenleri kopyalamayın. Boş yere bellek harcarsınız.
(gerekmedikçe niye kopyalayalım zaten)
7. Çıktılarınız sadece yazı içeriyorsa çift tırnak yerine tek tırnak kullanın. Çift tırnak olduğunda PHP çıktıda değişken arar.
(mantıklı)
8. SQL sorgularınızı döngülerin içine yazmayın.
(en mantıklısı)
9. Kullanmayacağınız eklentileri php.ini'den iptal edin.
(mantıklı)
10. include_once include'a oranla daha masraflıdır.
(mantıklı sayılır çokta önemli değil)
11. PHP'nizi güncelleyin. Yeni sürümler eskilerine oranla az da olsa daha hızlı.
(mantıklı)
Bunların hepsini toplasanız yine de bir SQL sorgusu üzerinde yapacağınız optimizasyon kadar performans artışı sağlayamazsınız.
Bu yüzden öncelikle veritabanı ile ilgili optimizasyonları bitirdikten sonra belki zevk için bunlara dikkat edilebilir.
Benzer bir yazı burada da yazılmış. İsteyen arkadaşlar inceleyebilirler...
Tam da bugün bu yazıya benzer yabancı bir kaynak bulmuştum ama ingilizcem iyi olmadığından birşey anlamadım. :D Bu süper oldu teşekkürler...
Buradak pek çok yoruma. Özellikle de SQL Optimizasyonu konusuna katılıyorum. Birde bu SQL Optimizasyonu işini dilden bağımsız düşünmemiz gerek. Hangi dilde kod yazıyor olursanız olun eğer veritabanı işi yapacaksanız tabiri caiz ise "çatır çatır" sql yazmalısınız.
Şimdiye dek pek çok programcı ile çalıştım. Kimileri sql bilgileri yeterli olmadığı için sql tarafında yapılması gereken bir işlemi kod tarafında yapmaya çalışıyorlar.
Yani sql ile istenildiği şekilde veriyi filtre edilmiş olarak almak varken ham veriyi çekip kod ile o veri üzerinde filtre yapılmaya çalışılıyor. Ufak birkaç veri için bu sorun olmasa da veri miktarı arttıkça sisteme düşen yük tavan yaptığı gibi filtreyi de sql ile yapmadıkları için oturup tekrar kodda değişiklik yapmakla uğraşıyorlar.
Bence, döngüler ve karar kontrol mekanizmaları içerisinde php metodlarını kullanmak zaten başlı başına bir performans kaybı.
For döngüsü her gerçekleştiğinde count() metodu çalışıyor. Bunun yerine döngüden önce $data = count($foo); şeklinde bir kere toplamı alıp daha sonra bu sayı üzerinden döngüyü gerçekleştirsek daha hızlı olmaz mı?
Bunun dışında somut düşünelim. Server'daki en yavaş parça hangisi? (HDD) O zaman bizim hız kazanmamız için HDD ile olan ilişiğimizi en aza indirmemiz gerekiyor. Memory engine'lar hariç database neyin üzerinde çalışıyor?(HDD).
O zaman performans için SQL bilgimizi geliştirmemiz gerekiyor. Daha sonra yazılımsal ve donanımsal caching ile HDD'ten ilişiğimizi kesiyoruz.
Gzip ile şıkıştırma işlemi, söylendiği gibi içeriği server-side'ta sıkıştırarak client-side'ta tekrar açıyor ama server bu işlemi yapabilmek için ne kullanıyor?(CPU)
Google'un Chrome için geliştirmiş olduğu Gear add-on'u gerçekten güzel bir özellik. İncelemenizi öneririm. User'ın memory'sini database olarak kullanabiliyorsunuz. :)
Sanırım Gear artık geliştirilmeyecek. Onun yerine HTML5'te Javascript'le aynı (hemen hemen aynı) işi yapan openDatabase fonksiyonu kullanılabilir.
http://webkit.org/demos/sticky-notes/index.html
http://ajaxian.com/archives/webkit-does-html5-client-side-database-storage
http://www.whatwg.org/specs/web-apps/current-work/
evet firefoxta da yeni javascript özellikler geldi.
eskiden güvenlik nedeniyle javascript istemcinin fiziksel dizinlerinde gezinemez, misal bir resmi ön izleme olarak sayfaya basamazdık.
ancak artık kullanıcının fiziksel sürücülerinde resim müzik video erişimi yapabiliyoruz.
pillinetwork sitelerine yorum ekleyebilmek ve daha fazlası için, üye olun ya da giriş yapın.
Nokta ve pilli ortak yapımı olan kodaman.org hep birlikte içerik üretip gelirini yazarları ile paylaştığımız kolektif bir kod yazarları blogudur. Siz de katılabilirsiniz.