Php try-catch Performans

8 Cevap php

Performans etkileri ne tür php 5 try-catch ifadeleri kullanırken dikkat edilmesi vardır?

Ben daha önce internet üzerinde bu konuda bazı eski ve görünüşte çelişkili bilgiler okudum. Şu anda php 4 oluşturulan ve php 5 incelikler pek yoksun oldu çalışmak zorunda çerçevenin bir sürü. Peki, ben php ile try-fiksatörleri kullanarak çok deneyim kendimi yok.

8 Cevap

Düşünün bir şey istisna atılır bir try'ın maliyeti aslında bir istisna atma ve yakalama maliyeti farklı bir soru olmasıdır.

Istisnalar sadece başarısız olgularda atılır eğer programın yürütme başına pek çok kez başarısız olmaz çünkü, neredeyse kesinlikle, performans umurumda değil. Eğer sıkı bir döngüde başarısız iseniz (aka: Bir tuğla duvara karşı baş vurarak), uygulama muhtemelen yavaş olmaktan daha kötü sorunları var. Eğer bir şekilde düzenli kontrol akışı için bunları kullanmak zorunda sürece Yani bir özel durum atma maliyeti hakkında endişelenmeyin.

Birisi bir istisna atar kod profilleme hakkında konuşurken bir yanıt gönderildi. Ben kendim hiç denemedim, ama ben güvenle bu sadece bir şey atmadan ve bir try bloğu dışına giderek daha çok daha büyük bir performans isabet gösterecektir tahmin.

Başka bir şey düşünmek size yuva derin seviyelerde bir çok çağırır nerede, hatta bu dönüş değerleri kontrol ve her aramada hataları yaymak için daha üst sağ yakalamak ... Bir tek denemek için hızlı olmasıdır.

Eğer ... catch deneyin kendi içinde her çağrıyı sarma olduğunuzu bulmak durum, tersi olarak, kod yavaş olacaktır. Ve çirkin.

Ben sıkıldım ve (ben zamanlama kodu dışında kalan) aşağıdaki profilli:

function no_except($a, $b) { 
    $a += $b;
    return $a;
}
function except($a, $b) { 
    try {
        $a += $b;
    } catch (Exception $e) {}
    return $a;
}

iki farklı döngüler kullanarak:

echo 'no except with no surrounding try';
for ($i = 0; $i < NUM_TESTS; ++$i) {
    no_except(5, 7);
}
echo 'no except with surrounding try';
for ($i = 0; $i < NUM_TESTS; ++$i) {
    try {
        no_except(5, 7);
    } catch (Exception $e) {}
}
echo 'except with no surrounding try';
for ($i = 0; $i < NUM_TESTS; ++$i) {
    except(5, 7);
}
echo 'except with surrounding try';
for ($i = 0; $i < NUM_TESTS; ++$i) {
    try {
        except(5, 7);
    } catch (Exception $e) {}
}

Benim WinXP kutusu çalışma apache ve PHP 5.2.6 1000000 ishal ile:

no except with no surrounding try = 3.3296
no except with surrounding try = 3.4246
except with no surrounding try = 3.2548
except with surrounding try = 3.2913

Bu sonuçlar tutarlı ve olursa olsun test koştu sipariş hangi benzer oranda kalmıştır.

Sonuç: Nadir istisnalar işlemek için kod ekleme sayar istisnalar kodlamak daha yavaştır.

Google'da Try / catch performansı üzerinde bir şey ama bir döngü 5000 bir döngü içinde yerine bir IF deyimi üretmek 329ms vs 6ms hatasını atma basit bir test bulamadım.

Genellikle beklenmedik arızalara karşı korumak için bir istisna kullanmak ve normal program devletin parçası olan hatalarına karşı kodunda hata denetimi kullanın. Göstermek için:

  1. Record veritabanında bulunamadı - geçerli bir durum, sen sorgu sonuçlarını kontrol ve uygun kullanıcı mesajlaşma edilmelidir.

  2. SQL hata ne zaman kayıt almaya çalışıyor - beklenmedik başarısızlığı, kayıt ya da orada olmayabilir, ancak bir program hatası var - bu bir istisna için iyi bir yerdir -, hata günlüğüne hata oturum yöneticisine yığın izleme e-posta ve ekran bir şeyler yanlış gitti ve bunun üzerinde çalışıyoruz ona danışmanlık kullanıcıya kibar bir hata mesajı.

İstisnalar pahalı, ama bunları kullanarak tüm program akışını ele sürece, herhangi bir performans farkı insan fark olmamalıdır.

Çok iyi bir soruydu!

Ben bunu birçok kez test edilmiş ve bu C + + 10 yıl önce doğruydu herhangi bir performans sorunu ;-) görmedim ama bugün onun kadar yararlı ve temizleyici beri bunu bir çok düzeldi düşünüyorum var.

Ama yine de benim ilk giriş noktası çevreleyen korkuyorum:

try {Controller::run();}catch(...)

Herkes zaten tamamen test etti mi .... fonksiyonları çağrı bol ve büyük dahil sınamak değil mi?

Maalesef çok eski bir mesajı yayınlamak, ama yorumları okudum ve ben biraz katılmıyorum, fark kodları basit bir parçası ile minimal olabilir veya Try / catch olmayan kod belirli kısımları için kullanılan nerede ihmal olabilir her zaman tahmin edilebilir, ama ben de (test değil) iman basit ki:

if(isset($var) && is_array($var)){
    foreach($var as $k=>$v){
         $var[$k] = $v+1;
    }
}

daha hızlı

try{
    foreach($var as $k=>$v){
        $var[$k] = $v+1;
    }
}catch(Exception($e)){
}

Ben de o (test değil) inanıyorum:

<?php
//beginning code
try{
    //some more code
    foreach($var as $k=>$v){
        $var[$k] = $v+1;
    }
    //more code
}catch(Exception($e)){
}
//output everything
?>

kodda ekstra IFS var daha pahalı

Try-catch blokları bir performans sorunu değil - gerçek performans darboğazı istisna nesneleri oluşturmak geliyor.

Test kodu:

function shuffle_assoc($array) { 
    $keys = array_keys($array);
    shuffle($keys);
    return array_merge(array_flip($keys), $array);
}

$c_e = new Exception('n');

function no_try($a, $b) { 
    $a = new stdclass;
    return $a;
}
function no_except($a, $b) { 
    try {
        $a = new Exception('k');
    } catch (Exception $e) {
        return $a + $b;
    }
    return $a;
}
function except($a, $b) { 
    try {
        throw new Exception('k');
    } catch (Exception $e) {
        return $a + $b;
    }
    return $a;
}
function constant_except($a, $b) {
    global $c_e;
    try {
        throw $c_e;
    } catch (Exception $e) {
        return $a + $b;
    }
    return $a;
}

$tests = array(
    'no try with no surrounding try'=>function() {
        no_try(5, 7);
    },
    'no try with surrounding try'=>function() {
        try {
            no_try(5, 7);
        } catch (Exception $e) {}
    },
    'no except with no surrounding try'=>function() {
        no_except(5, 7);
    },
    'no except with surrounding try'=>function() {
        try {
            no_except(5, 7);
        } catch (Exception $e) {}
    },
    'except with no surrounding try'=>function() {
        except(5, 7);
    },
    'except with surrounding try'=>function() {
        try {
            except(5, 7);
        } catch (Exception $e) {}
    },
    'constant except with no surrounding try'=>function() {
        constant_except(5, 7);
    },
    'constant except with surrounding try'=>function() {
        try {
            constant_except(5, 7);
        } catch (Exception $e) {}
    },
);
$tests = shuffle_assoc($tests);

foreach($tests as $k=>$f) {
    echo $k;
    $start = microtime(true);
    for ($i = 0; $i < 1000000; ++$i) {
        $f();
    }
    echo ' = '.number_format((microtime(true) - $start), 4)."<br>\n";
}

Sonuçlar:

no try with no surrounding try = 0.5130
no try with surrounding try = 0.5665
no except with no surrounding try = 3.6469
no except with surrounding try = 3.6979
except with no surrounding try = 3.8729
except with surrounding try = 3.8978
constant except with no surrounding try = 0.5741
constant except with surrounding try = 0.6234

Genel olarak, onlar PHP pahalı ve değerli değilsin.

Bir kontrol ifadeler dil olduğundan, bir istisna atar bir şey yakalamak zorundadır.

Eski atmak değil kodu ve yok yeni kodu ile uğraşırken, sadece karışıklığa yol açar.

İyi şanslar!