Merhaba arkadaşlar bugün klasorden dosya isimlerini alma işlemlerinin bi kaç yöntemini teste tuttum ve sonucları  burda paylaşmak istedim. klasör tarama işlemlerinde hiç düşünmeden kullandığım glob() fonksiyonu ne yazık ki beni hüsrana uğrattı.

ilk önce test ortamını tanıtmak istiyorum :

PHP  Versiyonu  : 5.3.2
Apache Versiyonu : 2.2
İşlemci : AMD Turion 64 X2 2.20 GHZ
Ram    : 4 GB

işte denemeler;

0
1
2
3
4
5
6
foreach(glob('*') as $dosya_ve_klasorler)
    {
        if( !is_dir($dosya_ve_klasorler) ) // ".." ve "." yı elemek için.
        {
            $dosyalar[] = $dosya_ve_klasorler;
        }
    }

Dosya Adeti : 1096
İşlem Süresi : 0.838 sn

0
1
2
3
4
5
 foreach(glob('*', GLOB_NOSORT) as $dosya_ve_klasorler) {
        if( !is_dir($dosya_ve_klasorler) )
        {
            $dosyalar[] = $dosya_ve_klasorler;
        }
    }

Dosya Adeti : 1096
İşlem Süresi : 0.801 sn

0
1
2
3
4
  foreach(glob('*', GLOB_NOSORT) as $dosya_ve_klasorler) {
 
        $dosyalar[] = $dosya_ve_klasorler;
 
    }

Dosya Adeti : 1096
İşlem Süresi : 0.147 sn

ilk büyük farkı burda gördük. is_dir kontrolu bizi 8 kat yavaşlatmış. devam ediyoruz.

0
1
2
3
4
5
6
7
  foreach (scandir('.') as $dosya_ve_klasorler)
    {
        if (is_dir($dosya_ve_klasorler))
        {
            continue;
        }
        $dosyalar[] = $dosya_ve_klasorler;
    }

Dosya Adeti : 1096
İşlem Süresi : 0.702 sn

glob fonksiyonunun is_dir ile beraber kullanılması ve scandir in is_dir ile beraber kullanılması arasında da pek fark göremedik. şimdi is_dir yerine preg_match kullanalm. (glob un yaptığı işi yapalım )

0
1
2
3
4
5
6
7
 foreach (scandir('.') as $dosya_ve_klasorler)
    {
        if (is_dir($dosya_ve_klasorler) || !preg_match('/test/i',$dosya_ve_klasorler) )
        {
            continue;
        }
        $dosyalar[] = $dosya_ve_klasorler;
    }

Dosya Adeti : 1088
İşlem Süresi : 0.701 sn

şimdi is_dir fonksiyonunua aradan cıkarıp farka bakalım.

0
1
2
3
4
5
6
7
 foreach (scandir('.') as $dosya_ve_klasorler)
    {
        if ( !preg_match('/test/i',$dosya_ve_klasorler) )
        {
            continue;
        }
        $dosyalar[] = $dosya_ve_klasorler;
    }

Dosya Adeti : 1088
İşlem Süresi : 0.013 sn

evet inanılmaz büyük bir fark. bu işlemden sonra for ile ilgili bir tes yapmak istiyordum ama burdaki küçük rakamlar benim coooook büyük bir dizi ile test etmem gerektiğini ortaya koyuyor son olarak readdir ile test edip bu testimizi de burda bitirelim

0
1
2
3
4
5
6
7
8
9
10
 $dir=opendir('.');
    while ($dosya_ve_klasorler=readdir($dir))
    {
 
        if ( !preg_match('/test/i',$dosya_ve_klasorler) )
        {
            continue;
        }
        $dosyalar[] = $dosya_ve_klasorler;
    }
    closedir($dir);

Dosya Adeti : 1088
İşlem Süresi : 0.011 sn

scandir ile arasında pek fark olmasa da galibimiz readdir. kendi glob gonksiyonumuzu yazıp kullanabiliriz. işte globdan daha hızlı glob fonskyionumuz(:

fonksiyonumuz :

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    function myGlob($dir,$pattern)
    {
        $dosyalar=array();
        $dir=opendir($dir);
        while ($dosya_ve_klasorler=readdir($dir))
        {
 
            if (!preg_match($pattern,$dosya_ve_klasorler) )
            {
                continue;
            }
            $dosyalar[] = $dosya_ve_klasorler;
        }
        closedir($dir);
        return $dosyalar;
    }

şimdi teste tutalım (:

0
 $dosyalar = myGlob('.','/test/i');

Dosya Adeti : 1088
İşlem Süresi : 0.012 sn

iyi çalışmalar (:

Merhaba arkadaşlar bu gece itibari ile (07.06.2010) yeni php kategorimi açmış bulunuyorum. Bugune kadar hep başı siteleriyle belada olan arkadaşlarımıza Optimizasyon tavsiye ettik.Siz de bu “optimizasyon yap(tır)malısın” lafını duymuşsunuzdur. Ama hiç kimseye optimizasyon konusuna nerden başlamalı ya da nasıl başmalı bilgilerini verdiğimi hatırlamıyorum. Optimizasyon önemli.! Bunu Yapın.! Bu yazımda PHP Optimizasyonuna giriş yapmakla beraber ilk tavsiyelerimi de yazmak istiyorum.

PHP ‘yi küçümsemeyin.!

Optimizasyon konusunda değinmek istediğim en önemli şey bu aslında. optimizasyon sadece aşırı tekrar ve ya yanlış seçimlerden kaçmaktır bana göre yani yazdığı şeyi daha doğru yazmaktır. optimizasyon kaynak kullanımında pintilik yapmak değildir. PHP düşündüğünüz kadar küçük bir dil değil. Yazarken korkmayın ( Optimizasyona ihtiyac duyulursa yapın phpnin yeteneklerinden yararlanmayı bilin.) Bana göre esneklikoptimizasyondan önce gelir. İkisi bir arada olmaz mı ? İşte bu kategoriyi açmamın sebebi buydu. Hem esnek hem stabil kod yazabilmek.

Kodunuzu satır satır profillendirin ,tanıtın.

Kodlarınızı her zaman üçüncü bir şahıs okuyacakmış gibi yazmaya çalışın. Ne yapmak istediğinizi karşıdakine anlatırken gereksiz kodlardan kaçındığınızı göreceksiniz.Ve yavaşlatabilecek kısımları da biliyor olacaksınız. Scriptinizi hızlandırma çalışmalarına başlamadan önce scripti yavaşlatan kod bloklarını keşfedin  nereyi optimize edeceğinizi bilin. Ve optimize edeceğiniz yeri bilmeden kodda düzenleme yapmaya başlamayın .!

bunun için güzel bir araç olan APD ye burdan ulaşabilrsiniz.

Yol haritanız olsun.

Scriptiniz üzerinde yapcağınız işlemler önceden planlanmış işlemler olsun (asla plansız kod yazmaya başlamayın). yapacağız optimize işlemleri dahi önceden bir yerlere yazılmış olsun. Bu size hem hız katacaktır hem düzen. Haritanızda Scriptinize versiyon vermeye de çalışın.

En güncel PHP versiyonunu kullanın.

PHP motorunun geliştiricileri de yıllardır performans için düzenlemeler yapıyor.! Bu yüzden PHP yi küçümsemeyin demiştik. Optimizasyon yapmadan ya da yaptırmadan önce ya da hızından şikayet etmeden once php versiyonunuzu yükseltin. versiyon yükseltme işlemlerini de her zaman php.net ten takip edebilirsiniz.

  • Migrating from PHP 4 to PHP 5.0.x
  • Migrating from PHP 5.0.x to PHP 5.1.x
  • Migrating from PHP 5.1.x to PHP 5.2.x
  • Cache mekanizmanızı kurun.

    Ne kadar statik o kadar hız. Cache yapayım derken de abarmayın. Tüm çıktıların saklanması cache değildir ..  Dinamikliği ya da yeniden oluşumu minimuma indirmeye çalışın. Veritabanına kayıtlı olan her şey sayfanızın her işlenmesinde tekrar tekrar sorgulanıp gelmesin. Mekanizmanız extra maliyetler ya da kaynak gereksinimi getirmesin veriyi size hızlı veren  bir uygulama kullanın örn :  Memcache Tema işlemleriniz için de Cache oluşturamıyorsanız Smarty gibi bir uygulama kullanın.

    Output buffer ‘a hükmedin.

    PHP’nin ik önce bellekte oluşturduğu output kullanıcıyı bekletir ve çıktı bitene kadar bellekte birikir. bu birikme sayfalarınızın geç yüklenmesine sebep olabilir. Bazı işlemlerinizde Output ‘u dışarı vermeye zorlayabilir ve hızlandırabilirsiniz.

    Output Buffering Control 

    Getter ve Setter metodlardan kaçının

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    class Yazilimci{
        public $name='';
     
        public function setName( $name )
        {
                 $this->name = $name;
     
         }
         public function getName()
         {
               return $this->name;
         }
    }

    Şu kodda gördüğünüz gibi setName() ve getName() size name elemanını saklamak ve vermek dışında hiç birşey yapmıyor.

    0
    1
    2
    
    $yazilimci=new Yazilimci;
    $yazilimci->setName('Tufan Barış YILDIRIM');
    echo $yazilimci->getName();

    setName() fonksiyonunda yapmak istediklerimiz olursa. ( onNameChanged olayı gibi ) o zaman bu metodların bir anlamı olur.

    Direk name elemanını kullanmanız hızını %100 arttıracaktır.

    0
    1
    2
    
    $yazilimci=new Yazilimci;
    $yazilimci->name='Tufan Barış YILDIRIM';
    echo $yazilimci->name;

    Gerek duymadıkça kopya değişkenler oluşturmayın

    PHP scriptlerimizde dışardan parametre alma ihtiyacı duyarız. Bu son kullanıcıya sağladığımız ya da programlamada kendimize sağladığımız bir kolaylık olabilir. Bu parametrelerin de bir süzgece ihtiyacı vardır “cleaner functions”  . Dışardan bize  500 KB boyutunda bir verinin textare aracılığı ile gönderildiğini düşünelim. bizim bunu yeni bir dğeişkene atamamız 1 MB bellek harcamamız anlamına gelir.

    0
    1
    
       $konuMetni = strip_tags($_POST['konu_metni']);
       echo $konuMetni;

    Inline operasyonlar yapın ram kullanımızı çok düşürecektir.

    0
    
    echo strip_tags($_POST['konu_metni']);

    Kullandığınız veritabanının yeteneklerini öğrenin.!

    Veritabanı sadece veri saklamak için değildir.! Veritabanı  hızlı ve düzenli ulaşım  ve saklama yapabilir. Yeteneklerinden en iyi şekilde faydalanmamız demek sorguların azalması , bu da hızın artması demektir. 

    Döngü içine sorgu yazmak yerine JOIN , istisnai durumlar da SUB QUERY  işlemlerine başvurmalıyız. 
    Çoklu insert örneği vermemiz gerekirse

    0
    1
    2
    3
    
    foreach ($yazilimcilar as  $yazilimci) {
      $query = 'INSERT INTO  yazilimcilar (adi,soyadi) VALUES("' . $yazilimci['adi'] . '", "' . $yazilimci['soyadi'] . '")';
      mysql_query($query);
      }

    bu kullanım $yazilimcilar sayısı kadar mysql_query çalıştırmaya sebep olacaktır.
    MYSQL INSERT kalıbını incelediğimizde bunu tek sorgu ile yapabildiğimizi görüyoruz. O halde bu yeteneğinden faydalanalım.

    ..  devamı gelecek

    PHP ile aslında 5 ile beraber bize lambda operatörü olmasa da aynı kolaylığı sağlıyordu.! In line functions ozelliği olmasa bunu kullanmanın bir yolunu buluyorduk. Anonymous fonksiyonlar olmasa da create_function ile aynı işi görebiliyorduk. Eventlarımızı call_user_func ile hallediyorduk.
    Javascript yazarken hep keşke phpde de olsa dediğim in line functions ve lambda phpde closures ile beraber 5.3 te en esnek halini almış. kapalı fonksiyonlara da use parametresiyle çare bulmuşlar.

    0
    
     $myLambda= function($adi,$soyadi) { return $adi.'  '.$soyadi;};

    isimsiz fonksiyonumuz artık $myLambda(“Tufan”,”YILDIRIM”) gibi çağrılabilecek. lambda fonksiyonu objesini incelemek istediğimizde türünün Closures olduğunu goruyoruz. Reflection olayını  kolaylaştırma amaçlı yaptıkları Closures sınıfı incelenince anlaşılabiliyor.

    0
    1
    2
    3
    4
    5
    6
    7
    8
    
    object(Closure)#1 (1) {
      ["parameter"]=>
      array(2) {
        ["$adi"]=>
        string(10) "<required>"
        ["$soyadi"]=>
        string(10) "<required>"
      }
    }

    bu sınıfla bebaber incelememiz gereken bir de sihirbaz metod var “__invoke” C# ın Type sınıfını (Reflection olaylarının temeli) script esnekliğiyle sunabilmişler. bu olayların hepsi aslında php nin ” eval()  ” yeteneğiyle dolaylı da olsa yapabiliyorduk. başlıca Reflection elemanlarını da kısaca verelim

    get_included_files();

    get_defined_constants();
    get_defined_functions();
    get_defined_vars();

    get_declared_classes();
    get_declared_interfaces();

    get_called_class();

    get_class_methods();
    get_class_vars();
    get_parent_class();
    get_object_vars();

    get_extension_funcs();
    get_loaded_extensions();

    gettype();

    bu elemanlar bize self debugginden tutun da reflection olaylarına kadar cok iyi yardımcı olabiliyor. metodların işlevleri isimlerinden de anlaşılabildiği için fazla ayrıntıya girmiyorum . php.net ten inceleybilirsiniz. şimdi bahsettiğimiz __invoke  metodunu incelelim

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <?php
        class Lambda{
     
            private  $adi="Tufan Barış";
     
            public function __invoke($soyadi){
                return $this->adi.' '.$soyadi;
            }
        }
    ?>

    bu sınıftan bir objeyi Lambda gibi ($Object()) kullanmaya kaltığımızda tetiklenecek olan metod işimize ne kadar yaraycak bilmiyorum (Çok yetenekli bir plugin sistemi yapılabilir) ama reflection adına güzel bir çalışma olmuş. bkz: C# ta MethodInfo.Invoke

    kullanıcı tanımlı parametreler dışında bir de dışardan aldığı de farklı çözüm bulmuşlar demiştik şimdi bir de kullanıcının verdiği parametreler dışında alabileceği değişkenleri inceleyelim.

    0
    1
    2
    3
    4
    
     $ikinciAdi="Barış";
     $myLambda= function($adi,$soyadi) use ($ikinciAdi) { return $adi.'  '.$ikinciAdi.' '.$soyadi;};
     echo $myLambda("Tufan","YILDIRIM");
     
     // output :  Tufan Barış YILDIRIM

    Lambda Okunaklığı arttırır.

    0
    1
    2
    3
    4
    5
    6
    7
    
    function replace_spaces ($text) {
         if (!function_exists ('replace_spaces_helper')) {
           function replace_spaces_helper ($matches) {
             return str_replace ($matches[1], ' ', ' ').' ';
           }
         }
         return preg_replace_callback ('/( +) /', 'replace_spaces_helper', $text);
       }

    örneğimizi inceleyelim ilk once. bu metod örnekte replace_spaces fonksiyonu içinde isim verilerek bir fonksiyon daha tanımlanmış. bu fonksiyon her tetiklendiğinde tekrar oluşmaması için de function_exists() ile kontrol edilmiş. okunması zor ve oluşan hataları takip etmesi de zor. lambda örneğini de birazdan inceleyeceğiz.

    Not : Lambda runtime’da metod cağırma sınıf tanımlama yöntemi değildir. php bunu zaten yapar. bkz : __call,
    Lambda objeleri  parametre olarak “callback” ya da  “funcname” isteyen her heryerde kullanılabilir olarak tasarlanmıştır. aşağıdaki orneklerin inceleyelim.

       $lambda ();  // doğru kullanım
       call_user_func($lambda); // doğru kullanım
       call_user_func_array($lambda, array());  // doğru kullanım

     üç örnekte de gördüğümüz gibi  $lambda objemiz hem metod gibi hem callbackName gibi hem de funcName gibi kullanılabiliyor.

    lambda tekrar oluşturulmada hata vermez cünkü eşsiz bir isimle oluşturulur.

    örnek :

    0
    1
    2
    3
    4
    5
    
      function replace_spaces ($text) {
         $replacement = function ($matches) {
           return str_replace ($matches[1], ' ', ' ').' ';
         };
         return preg_replace_callback ('/( +) /', $replacement, $text);
       }

    lambda fonksiyonların en cok sevindiren ozelliği de inline yazılabilmesi :
    örnek :

      function replace_spaces ($text) {
        return preg_replace_callback ('/( +) /',
          function ($matches) {
            return str_replace ($matches[1], ' ', ' ').' ';
          }, $text);
      }

    Kapalı Fonksiyon desteği:

    0
    
    function (normal parameters) use ($var1, $var2, &$refvar) {}

    OOP kullanımda Clousers

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
         class Example {
           private $search;
     
           public function __construct ($search) {
             $this->search = $search;
           }
     
           public function setSearch ($search) {
             $this->search = $search;
           }
     
           public function getReplacer ($replacement) {
             return function ($text) use ($replacement) {
               return str_replace ($this->search, $replacement, $text);
             };
           }
         }
     
         $example = new Example ('hello');
         $replacer = $example->getReplacer ('goodbye');
         echo $replacer ('hello world'); // goodbye world
         $example->setSearch ('world');
         echo $replacer ('hello world'); // hello goodbye

    sınıf içerisinde kullanılan lambdalara kapalı olarak $this in verilesi sonradan kaldırılmış ve bunun acıklaması da şurda belirtimiş
    http://wiki.php.net/rfc/closures/removal-of-this

    Closures objelerinin Reflection Sınıfıyla beraber kullanılması :

    0
    1
    2
    3
    
    $m = new ReflectionMethod ($closure);
    $p = new ReflectionParameter ($closure, 0);
    $p = new ReflectionParameter ($closure, 'a');
    $p = new ReflectionParameter (array ($closure, '__invoke'), 0); // metodumuz yoksa __invoke veriyoruz

    Konuyla iligli araştırma yapmak isteyenlerin bu adresleri incelemelerini öneririm :
    http://wiki.php.net/rfc/closures
    http://wiki.php.net/rfc/closures/removal-of-this 
    http://msdn.microsoft.com/en-us/library/136wx94f(v=VS.100).aspx
    http://msdn.microsoft.com/en-us/library/system.type.aspx
    http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.aspx
    http://msdn.microsoft.com/en-us/library/bb397687.aspx

    iyi çalışmalar..

    OCI-Lob  sınıfını tanımıştık. bu sınıfın insert ve update  sorguları için kullanılan metodu olan OCI-Lob::save()  metodunu inceliyor olacağız.  Update sorgularımız için şartımıza uyan bir satır  yoksa php OCI_INVALID_HANDLE gibi bir hata fırlatıyor. update işlemlerini bir sonraki yazıda işleyeceğimiz için şimdilik sadece bahsedip geçiyoruz.

    OCI-Lob
    bool save ( string $data [, int $offset ] )

    save metodu LOB alanlara veri yazmak için kullanılır. OCI lob objelerinin indikasyon özelliği olduğundan  opsiyonel olarak  offset değeri de verebiliyoruz . yani istersek veriyi  lobun istediğimiz alanına yazabiliyoruz.

    işte örnek insert işlemi.

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    
    $conn=oci_connect(); // bağlantı ayarlarınız
     
    $sql = "INSERT INTO loblar
              (
                id,
                lobalan
              )
           VALUES
              (
                loblar_seq.NEXTVAL,
                -- Boş bir CLOB oluşturuyoruz
                EMPTY_CLOB()
              )
           RETURNING
              -- Lob locator dönderiyoruz
              lobalan INTO :mylob_loc";
     
    $stmt = oci_parse($conn, $sql);
     
    // Boş bir OCI-Lob objesi oluşturuyoruz
    $myLOB = oci_new_descriptor($conn, OCI_D_LOB);
     
    // LOB loactor a bağlıyoruz.
    oci_bind_by_name($stmt, ":mylob_loc", $myLOB, -1, OCI_B_CLOB);
     
    // Sorguyu çalıştıyoruz (Default Transaction modunda)
    oci_execute($stmt, OCI_DEFAULT)
        or die ("Unable to execute query\n");
     
    //  Lob alana şimdi istediğimizi yazdırıyoruz
    if ( !$myLOB->save('Tarih : '.date('H:i:s',time())) ) {
     
        // Hata olmuşsa geri sarıyoruz
        oci_rollback($conn);
     
    } else {
     
        // başarıyla yazabildiysek commit ediyoruz.
        oci_commit($conn);
     
    }
     
    // kaynakları boşaltıp  veritabanı bağlantısını kesiyoruz.
    oci_free_statement($stmt);
    $myLOB->free();
    oci_close($conn)

    Blob Compression konusunda bilgi almak için de şu konuyu okuyabilirsiniz

    Oracle Blob Compression

    © 2012 Tufan Suffusion theme by Sayontan Sinha