Bagaimana cara mengukur kecepatan kode yang ditulis dalam PHP? [Tutup]


118

Bagaimana saya bisa mengatakan kelas mana dari banyak (yang semuanya melakukan pekerjaan yang sama) mengeksekusi lebih cepat? apakah ada software untuk mengukurnya?

Jawaban:


195

Anda memiliki (setidaknya) dua solusi:

Yang cukup "naif" adalah menggunakan microtime (true) sebelum dan sesudah sebagian kode, untuk mengetahui berapa banyak waktu yang telah berlalu selama eksekusinya; jawaban lain mengatakan itu dan sudah memberi contoh, jadi saya tidak akan mengatakan lebih banyak lagi.

Ini adalah solusi yang bagus jika Anda ingin membandingkan beberapa instruksi; seperti membandingkan dua jenis fungsi, misalnya - lebih baik jika dilakukan ribuan kali, untuk memastikan setiap "elemen yang mengganggu" dirata-ratakan.

Sesuatu seperti ini, jadi, jika Anda ingin tahu berapa lama waktu yang dibutuhkan untuk membuat sebuah array:

$before = microtime(true);

for ($i=0 ; $i<100000 ; $i++) {
    serialize($list);
}

$after = microtime(true);
echo ($after-$before)/$i . " sec/serialize\n";

Tidak sempurna, tetapi berguna, dan tidak perlu banyak waktu untuk menyiapkannya.



Solusi lain, yang berfungsi cukup baik jika Anda ingin mengidentifikasi fungsi mana yang membutuhkan banyak waktu di seluruh skrip, adalah dengan menggunakan:

  • The Xdebug ekstensi, untuk menghasilkan profil data untuk script
  • Perangkat lunak yang membaca data pembuatan profil, dan menyajikan sesuatu yang dapat dibaca. Saya tahu tiga di antaranya:
    • Webgrind ; antarmuka web; harus berfungsi di server Apache + PHP apa pun
    • WinCacheGrind ; hanya di windows
    • KCacheGrind ; mungkin hanya Linux dan mirip-linux; Itu yang saya suka, btw

Untuk mendapatkan file profil, Anda harus menginstal dan mengkonfigurasi Xdebug; lihat halaman Profiling PHP Scripts di dokumentasi.

Apa yang biasanya saya lakukan adalah tidak mengaktifkan profiler secara default (ini menghasilkan file yang cukup besar, dan memperlambat segalanya) , tetapi menggunakan kemungkinan untuk mengirim parameter yang disebut XDEBUG_PROFILEsebagai GET data, untuk mengaktifkan profil hanya untuk halaman yang saya butuhkan.
Bagian terkait profil dari php.ini saya terlihat seperti ini:

xdebug.profiler_enable = 0              ; Profiling not activated by default
xdebug.profiler_enable_trigger = 1      ; Profiling activated when requested by the GET parameter
xdebug.profiler_output_dir = /tmp/ouput_directory
xdebug.profiler_output_name = files_names

(Baca dokumentasi untuk informasi lebih lanjut)

Tangkapan layar ini berasal dari program C ++ di KcacheGrind: (sumber: sourceforge.net ) Anda akan mendapatkan hal yang persis sama dengan skrip PHP ;-) (Maksud saya, dengan KCacheGrind; WinCacheGrind tidak sebagus KCacheGrind ... )http://kcachegrind.sourceforge.net/html/pics/KcgShot3Large.gif



Hal ini memungkinkan Anda untuk mendapatkan tampilan yang bagus dari apa yang membutuhkan waktu dalam aplikasi Anda - dan kadang-kadang pasti membantu untuk menemukan yang fungsi yang memperlambat segalanya bawah ^^

Perhatikan bahwa Xdebug menghitung waktu CPU yang dihabiskan oleh PHP; ketika PHP menunggu jawaban dari Database (misalnya), PHP tidak berfungsi; hanya menunggu. Jadi Xdebug akan menganggap permintaan DB tidak memakan banyak waktu!
Ini harus diprofilkan di server SQL, bukan PHP, jadi ...


Semoga ini membantu :-)
Selamat bersenang-senang!


1
Sebuah windows build dari QCacheGrind ada :-) sourceforge.net/projects/qcachegrindwin
François Breton

43

Untuk hal cepat saya melakukan ini (dalam PHP):

$startTime = microtime(true);
doTask(); // whatever you want to time
echo "Time:  " . number_format(( microtime(true) - $startTime), 4) . " Seconds\n";

Anda juga dapat menggunakan profiler seperti http://xdebug.org/ .


2
Untuk akurasi tambahan, saya sarankan (a) menggunakan loop dan rata-rata waktu dan (b) menggunakan file terpisah untuk setiap hal yang Anda uji. Jika Anda memiliki beberapa pengaturan waktu dalam satu skrip, urutannya terkadang dapat membuat perbedaan.
DisgruntledGoat

9

Saya telah membuat kelas waktu sederhana, mungkin berguna untuk seseorang:

class TimingHelper {

    private $start;

    public function __construct() {
        $this->start = microtime(true);
    }

    public function start() {
        $this->start = microtime(true);
    }

    public function segs() {
        return microtime(true) - $this->start;
    }

    public function time() {
        $segs = $this->segs();
        $days = floor($segs / 86400);
        $segs -= $days * 86400;
        $hours = floor($segs / 3600);
        $segs -= $hours * 3600;
        $mins = floor($segs / 60);
        $segs -= $mins * 60;
        $microsegs = ($segs - floor($segs)) * 1000;
        $segs = floor($segs);

        return 
            (empty($days) ? "" : $days . "d ") . 
            (empty($hours) ? "" : $hours . "h ") . 
            (empty($mins) ? "" : $mins . "m ") . 
            $segs . "s " .
            $microsegs . "ms";
    }

}

Menggunakan:

$th = new TimingHelper();
<..code being mesured..>
echo $th->time();
$th->start(); // if it's the case
<..code being mesured..>
echo $th->time();

// result: 4d 17h 34m 57s 0.00095367431640625ms 

Anda salah echo$echo
mengetik

9

Pembaruan 2020

Sudah bertahun-tahun sejak terakhir kali saya menjawab pertanyaan ini, jadi saya pikir ini perlu pembaruan pada lanskap APM.

  • AppDynamics telah dibeli oleh Cisco dan akun gratis selamanya yang biasa mereka tawarkan telah dikeluarkan dari situs web mereka.
  • NewRelic telah menurunkan harga mereka dari $ 149 / bulan / host menjadi $ 25 / bulan / host untuk bersaing dengan pendatang baru di pasar APM, Datadog yang menawarkan $ 31 / bulan / host.
  • Fitur Datadog APM masih ringan dan menyisakan banyak hal yang diinginkan. Namun, saya melihat mereka meningkatkan dan meningkatkan ini sepanjang tahun depan.
  • Ruxit telah dibeli oleh Dynatrace. Tidak heran di sini karena Ruxit dibangun oleh mantan Karyawan Dynatrace. Hal ini memungkinkan Dynatrace bertransformasi menjadi model SaaS yang sesungguhnya menjadi lebih baik. Ucapkan selamat tinggal pada klien Java yang besar itu jika Anda mau.
  • Ada opsi gratis / sumber terbuka sekarang juga. Lihat Apache Skywalking yang sangat populer di China di antara perusahaan teknologi top mereka dan PinPoint yang menawarkan demo yang dapat Anda coba sebelum menginstal. Keduanya mengharuskan Anda mengelola hosting jadi bersiaplah untuk menjalankan beberapa Mesin Virtual dan meluangkan waktu dengan instalasi dan konfigurasi.
  • Saya belum mencoba salah satu dari solusi APM sumber terbuka ini jadi saya tidak dalam posisi untuk merekomendasikannya, namun, saya secara pribadi telah berhasil menerapkan semua solusi APM ini untuk beberapa organisasi baik di lokasi maupun di awan untuk ratusan aplikasi / layanan mikro. Jadi saya dapat mengatakan dengan percaya diri, Anda tidak bisa salah dengan vendor mana pun jika mereka sesuai dengan tagihan Anda.


Awalnya Dijawab pada Oktober 2015

Berikut adalah jawaban langsung untuk pertanyaan Anda

apakah ada software untuk mengukurnya?

Ya ada. Saya bertanya-tanya mengapa belum ada yang menyebutkannya. Meskipun jawaban yang disarankan di atas tampaknya baik-baik saja untuk pemeriksaan cepat tetapi tidak dapat diskalakan dalam jangka panjang atau untuk proyek yang lebih besar.

Mengapa tidak menggunakan alat Pemantauan Kinerja Aplikasi (APM) yang dibuat persis untuk itu dan banyak lagi. Lihat NewRelic, AppDynamics, Ruxit (semuanya memiliki versi gratis) untuk memantau waktu eksekusi, penggunaan sumber daya, throughput setiap aplikasi ke tingkat metode.


6

Jika Anda ingin menguji kinerja kerangka kerja dengan cepat, Anda dapat memasukkan file index.php

//at beginning
$milliseconds = round(microtime(true) * 1000);

//and at the end
echo round(microtime(true) * 1000) - $milliseconds;

Setiap kali Anda akan mendapatkan waktu eksekusi dalam milidetik . Karena mikrodetik tidak terlalu berguna dalam menguji kasus kerangka kerja.



4

Saya ingin berbagi dengan Anda fungsi buatan sendiri yang saya gunakan untuk mengukur kecepatan fungsi yang ada hingga 10 argumen:

function fdump($f_name='', $f_args=array()){

    $f_dump=array();
    $f_result='';

    $f_success=false;

    $f_start=microtime();
    $f_start=explode(' ', $f_start);
    $f_start=$f_start[1] + $f_start[0];

    if(function_exists($f_name)){

        if(isset($f_args[0])&&is_array($f_args[0])){
            if($f_result=$f_name($f_args)){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[1])){
            if($f_result=$f_name($f_args[0])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[2])){
            if($f_result=$f_name($f_args[0],$f_args[1])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[3])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[4])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[5])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[6])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[7])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[8])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[9])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[10])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8],$f_args[9])){
                $f_success=true;
            }
        }
    }
    $f_end=microtime();
    $f_end=explode(' ', $f_end);
    $f_end=$f_end[1] + $f_end[0];

    $f_time=round(($f_end - $f_start), 4);
    $f_dump['f_success']=$f_success;
    $f_dump['f_time']=$f_time;
    $f_dump['f_result']=$f_result;

    var_dump($f_dump);exit;

    //return $f_result;

}

Contoh

function do_stuff($arg1='', $arg2=''){
    return $arg1.' '.$arg2;
}

fdump('do_stuff',array('hello', 'world'));

Kembali

  array(3) {
    ["f_success"]=>
    bool(true)
    ["f_time"]=>
    float(0)            //too fast...
    ["f_result"]=>
    string(11) "hello world"
  }

3

Jika itu sesuatu yang dapat diuji di luar konteks Web, saya hanya menggunakan timeperintah Unix .


3

Zend Studio telah membangun dukungan untuk pembuatan profil menggunakan XDebug atau ZendDebugger. Ini akan membuat profil kode Anda, memberi tahu Anda berapa lama waktu yang dibutuhkan setiap fungsi. Ini adalah alat yang luar biasa untuk mencari tahu di mana kemacetan Anda.


1

Anda dapat menggunakan hal-hal dasar seperti menyimpan stempel waktu atau microtime () sebelum dan sesudah operasi untuk menghitung waktu yang dibutuhkan. Itu mudah dilakukan, tetapi tidak terlalu akurat. Mungkin solusi yang lebih baik adalah Xdebug , saya belum pernah bekerja dengannya tetapi tampaknya itu adalah debugger / profiler PHP paling terkenal yang dapat saya temukan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.