Cara termudah untuk membuat profil skrip PHP

289

Apa cara termudah untuk membuat profil skrip PHP?

Saya senang sekali menempelkan sesuatu yang menunjukkan kepada saya dump semua panggilan fungsi dan berapa lama waktu yang saya butuhkan, tetapi saya juga setuju dengan menempatkan sesuatu di sekitar fungsi tertentu.

Saya mencoba bereksperimen dengan fungsi mikrotim :

$then = microtime();
myFunc();
$now = microtime();

echo sprintf("Elapsed:  %f", $now-$then);

tapi itu terkadang memberi saya hasil negatif. Ditambah lagi, banyak masalah untuk memercikkan seluruh kode saya.

Mark Biek
sumber
7
hei Mark, lihat komentar ini untuk membantu Anda menyelesaikan komentar negatif: ro.php.net/manual/en/function.microtime.php#99524
Mina
16
Komentar yang ditautkan oleh @Midiane tidak masuk akal. Jika itu tampaknya menyelesaikan masalah komentator, itu pasti kebetulan. Hanya menggunakan microtime()akan menyebabkan kadang-kadang mengevaluasi ekspresi seperti: "0.00154800 1342892546" - "0.99905700 1342892545", yang akan mengevaluasi seperti: 0.001548 - 0.999057. Anda dapat menggunakan microtime( TRUE )untuk menghindari masalah itu, seperti yang ditunjukkan oleh @luka.
JMM

Jawaban:

104

The PECL APD ekstensi digunakan sebagai berikut:

<?php
apd_set_pprof_trace();

//rest of the script
?>

Setelah itu, parsing file yang dihasilkan menggunakan pprofp.

Contoh output:

Trace for /home/dan/testapd.php
Total Elapsed Time = 0.00
Total System Time  = 0.00
Total User Time    = 0.00


Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
100.0 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0000   0.0009            0 main
56.9 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0005   0.0005            0 apd_set_pprof_trace
28.0 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 preg_replace
14.3 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 str_replace

Peringatan: rilis APD terbaru bertanggal 2004, ekstensi tidak lagi dipertahankan dan memiliki berbagai masalah kompabilitas (lihat komentar).

Vincent
sumber
19
Ekstensi APD rusak di php 5.4.
Skynet
Sebagai balasan kepada user457015, saya bisa membuatnya bekerja di situs web yang menjalankan wordpress 3.8.1 dan PHP 5.3.10 dan sepertinya berfungsi dengan baik.
Supernovah
1
@Supernovah, user457015 mengatakan PHP 5.4. Dia tidak mengatakan itu rusak di PHP 5.3.
Magnus
@ user1420752 Saya menjalankan 5.3.27 dan tidak berjalan di sana juga. Saya mendapatkan kesalahan fungsi yang tidak ditentukan.
Fractaly
2
Rilis terbaru dari APD adalah dari 2004 (!) Tidak berfungsi dengan PHP 7. Ketika mencoba menginstal untuk PHP 5 dengan pecl install apd, itu memberikan pesan kesalahan tentang "config.m4". Sepertinya Anda harus menginstalnya dari sumber, yang belum saya coba. Serius, bukankah ada alat profilinging modern berbasis CLI yang diperbarui untuk PHP yang diinstal dengan Homebrew, membutuhkan pengaturan minimal dan memberikan hasil yang mudah dibaca manusia?
sebagainyarin
267

Anda ingin xdebug, saya pikir. Instal di server, hidupkan, pompa output melalui kcachegrind (untuk linux) atau wincachegrind (untuk windows) dan itu akan menunjukkan kepada Anda beberapa grafik cantik yang merinci waktu, jumlah, dan penggunaan memori yang tepat (tetapi Anda akan perlu ekstensi lain untuk itu).

Itu batu, serius: D

mercutio
sumber
6
Saya menemukan ini jauh lebih mudah diimplementasikan daripada solusi APD. Tapi mungkin itu karena beberapa alasan APD tidak dapat dikompilasi dengan baik di sistem saya. Grafik kcachegrind juga secantik yang dijanjikan.
wxs
1
@EvilPuppetMaster, Anda perlu mengkompilasi php dengan --enable-memory-limit atau menggunakan versi php yang lebih modern. Lihat xdebug.org/docs/basic#xdebug_memory_usage
mercutio
52
xdebug + webgrind dengan cepat menjadi senjata pilihan saya untuk profil yang cepat dan mudah. code.google.com/p/webgrind
xkcd150
6
xdebug + xdebug_start_trace () + xdebug_stop_trace () = win
quano
3
Ini sangat mudah untuk bekerja pada Windows dengan XAMPP. Netbeans sudah dikonfigurasikan untuk xdebug. Satu-satunya hal yang perlu Anda lakukan adalah mengubah pengaturan xdebug di php.ini ke xdebug.profiler_output_name = "cachegrind.out.% T-% s" atau tidak ada output yang akan dihasilkan. Membutuhkan restart apache.
beginner_
97

Tidak diperlukan ekstensi, cukup gunakan dua fungsi ini untuk pembuatan profil sederhana.

// Call this at each point of interest, passing a descriptive string
function prof_flag($str)
{
    global $prof_timing, $prof_names;
    $prof_timing[] = microtime(true);
    $prof_names[] = $str;
}

// Call this when you're done and want to see the results
function prof_print()
{
    global $prof_timing, $prof_names;
    $size = count($prof_timing);
    for($i=0;$i<$size - 1; $i++)
    {
        echo "<b>{$prof_names[$i]}</b><br>";
        echo sprintf("&nbsp;&nbsp;&nbsp;%f<br>", $prof_timing[$i+1]-$prof_timing[$i]);
    }
    echo "<b>{$prof_names[$size-1]}</b><br>";
}

Berikut ini adalah contoh, memanggil prof_flag () dengan deskripsi di setiap pos pemeriksaan, dan prof_print () di akhir:

prof_flag("Start");

   include '../lib/database.php';
   include '../lib/helper_func.php';

prof_flag("Connect to DB");

   connect_to_db();

prof_flag("Perform query");

   // Get all the data

   $select_query = "SELECT * FROM data_table";
   $result = mysql_query($select_query);

prof_flag("Retrieve data");

   $rows = array();
   $found_data=false;
   while($r = mysql_fetch_assoc($result))
   {
       $found_data=true;
       $rows[] = $r;
   }

prof_flag("Close DB");

   mysql_close();   //close database connection

prof_flag("Done");
prof_print();

Output terlihat seperti ini:

Mulai
   0,004303
Terhubung ke DB
   0,003518
Lakukan kueri
   0,000308
Ambil data
   0,000009
Tutup DB
   0,000049
Selesai

TimH - Codidact
sumber
37

Lintas memposting referensi saya dari SO Documentation beta yang sedang offline.

Pembuatan profil dengan XDebug

Perpanjangan ke PHP yang disebut Xdebug tersedia untuk membantu dalam pembuatan profil aplikasi PHP , serta debugging runtime. Saat menjalankan profiler, output ditulis ke file dalam format biner yang disebut "cachegrind". Aplikasi tersedia di setiap platform untuk menganalisis file-file ini. Tidak ada perubahan kode aplikasi yang diperlukan untuk melakukan profil ini.

Untuk mengaktifkan profil, instal ekstensi dan sesuaikan pengaturan php.ini. Beberapa distribusi Linux datang dengan paket standar (mis. php-xdebugPaket Ubuntu ). Dalam contoh kami, kami akan menjalankan profil secara opsional berdasarkan parameter permintaan. Ini memungkinkan kami untuk menjaga pengaturan statis dan mengaktifkan profiler hanya sesuai kebutuhan.

# php.ini settings
# Set to 1 to turn it on for every request
xdebug.profiler_enable = 0
# Let's use a GET/POST parameter to turn on the profiler
xdebug.profiler_enable_trigger = 1
# The GET/POST value we will pass; empty for any value
xdebug.profiler_enable_trigger_value = ""
# Output cachegrind files to /tmp so our system cleans them up later
xdebug.profiler_output_dir = "/tmp"
xdebug.profiler_output_name = "cachegrind.out.%p"

Selanjutnya gunakan klien web untuk membuat permintaan ke URL aplikasi Anda yang ingin Anda profil, misalnya

http://example.com/article/1?XDEBUG_PROFILE=1

Saat halaman memprosesnya akan menulis ke file dengan nama yang mirip dengan

/tmp/cachegrind.out.12345

Secara default nomor dalam nama file adalah id proses yang menulisnya. Ini dapat dikonfigurasi dengan xdebug.profiler_output_namepengaturan.

Perhatikan bahwa itu akan menulis satu file untuk setiap permintaan / proses PHP yang dieksekusi. Jadi, misalnya, jika Anda ingin menganalisis posting formulir, satu profil akan ditulis untuk permintaan GET untuk menampilkan formulir HTML. Parameter XDEBUG_PROFILE perlu diteruskan ke permintaan POST berikutnya untuk menganalisis permintaan kedua yang memproses formulir. Karenanya saat membuat profil, kadang-kadang lebih mudah menjalankan curl ke POST suatu formulir secara langsung.

Menganalisa Output

Setelah ditulis, cache profil dapat dibaca oleh aplikasi seperti KCachegrind atau Webgrind . PHPStorm, IDE PHP populer, juga dapat menampilkan data profil ini .

KCachegrind

KCachegrind, misalnya, akan menampilkan informasi termasuk:

  • Fungsi dijalankan
  • Waktu panggilan, baik itu sendiri maupun termasuk panggilan fungsi berikutnya
  • Frekuensi setiap fungsi dipanggil
  • Grafik panggilan
  • Tautan ke kode sumber

Apa yang dicari

Tentunya penyetelan kinerja sangat spesifik untuk setiap kasus penggunaan aplikasi. Secara umum ada baiknya mencari:

  • Panggilan berulang ke fungsi yang sama yang tidak Anda harapkan untuk dilihat. Untuk fungsi yang memproses dan meminta data, ini bisa menjadi peluang utama bagi aplikasi Anda untuk melakukan cache.
  • Fungsi berjalan lambat. Di mana aplikasi menghabiskan sebagian besar waktunya? hasil terbaik dalam penyetelan kinerja berfokus pada bagian-bagian aplikasi yang paling banyak menghabiskan waktu.

Catatan : Xdebug, dan khususnya fitur profilnya, sangat padat sumber daya dan memperlambat eksekusi PHP. Disarankan untuk tidak menjalankan ini di lingkungan server produksi.

Matt S
sumber
3
Menambahkan ke daftar alat untuk mengurai cache profil: PhpStorm juga memiliki alat untuk melihat dulu cache profil
peterchaula
1
@ Peter saya lupa PHPStorm memiliki fitur itu. Saya telah menambahkannya dengan tautan ke dokumentasi. Terima kasih!
Matt S
Adakah cara untuk mendapatkan laporan teks (non-GUI) langsung di server?
Alexander Shcheblikin
1
@Ark, bisakah Anda menandai ini sebagai jawabannya? Jawaban saat ini sudah kedaluwarsa bahkan ketika diposting dan tidak bekerja selama bertahun-tahun. Ini berhasil, dan saya tahu tidak ada metode yang lebih baik.
Mawg mengatakan mengembalikan Monica
24

Jika mengurangi microtimes memberi Anda hasil negatif, coba gunakan fungsi dengan argumen true( microtime(true)). Dengan true, fungsi mengembalikan float bukan string (seperti halnya jika ia dipanggil tanpa argumen).

luka
sumber
24

Jujur, saya akan berpendapat bahwa menggunakan NewRelic untuk profil adalah yang terbaik.

Ini adalah ekstensi PHP yang tampaknya tidak memperlambat runtime sama sekali dan mereka melakukan pemantauan untuk Anda, memungkinkan penelusuran yang layak. Dalam versi yang mahal, mereka mengizinkan pencarian yang berat (tapi kami tidak mampu membeli model harganya).

Namun, bahkan dengan paket gratis / standar, jelas dan sederhana di mana sebagian besar buah yang menggantung rendah. Saya juga suka itu bisa memberi Anda ide tentang interaksi DB juga.

tangkapan layar dari salah satu antarmuka saat membuat profil

zeroasterisk
sumber
16
Relic baru terlihat menjanjikan, tentu saja. Namun, "Pengungkapan Data Aplikasi Anda" bagian dari Kebijakan Privasi mereka langsung memukul saya. Saya juga, berbagi potongan kode sumber milik dengan pihak ketiga sedikit terlalu banyak.
Cengiz Can
8
Tidak melompat ke pertahanan mereka di sini, tetapi sepertinya "Data Aplikasi" hanyalah info kinerja dan info konfigurasi sistem, bukan kode sumber aplikasi Anda.
David Shields
Pertama, relik baru saya menunjukkan "WebTransaction" saya sebagai 99%, dan tidak memiliki akun pro untuk "ApplicationTraces"
Karthik T
1
coba mendaftar di: newrelic.com/rackspace <seharusnya memberi Anda "standar" gratis
zeroasterisk
15

Profil orang miskin, tidak perlu ekstensi. Mendukung profil bersarang dan persentase total:

function p_open($flag) {
    global $p_times;
    if (null === $p_times)
        $p_times = [];
    if (! array_key_exists($flag, $p_times))
        $p_times[$flag] = [ 'total' => 0, 'open' => 0 ];
    $p_times[$flag]['open'] = microtime(true);
}

function p_close($flag)
{
    global $p_times;
    if (isset($p_times[$flag]['open'])) {
        $p_times[$flag]['total'] += (microtime(true) - $p_times[$flag]['open']);
        unset($p_times[$flag]['open']);
    }
}

function p_dump()
{
    global $p_times;
    $dump = [];
    $sum  = 0;
    foreach ($p_times as $flag => $info) {
        $dump[$flag]['elapsed'] = $info['total'];
        $sum += $info['total'];
    }
    foreach ($dump as $flag => $info) {
        $dump[$flag]['percent'] = $dump[$flag]['elapsed']/$sum;
    }
    return $dump;
}

Contoh:

<?php

p_open('foo');
sleep(1);
p_open('bar');
sleep(2);
p_open('baz');
sleep(3);
p_close('baz');
sleep(2);
p_close('bar');
sleep(1);
p_close('foo');

var_dump(p_dump());

Hasil:

array:3 [
  "foo" => array:2 [
    "elapsed" => 9.000766992569
    "percent" => 0.4736904954747
  ]
  "bar" => array:2 [
    "elapsed" => 7.0004580020905
    "percent" => 0.36841864946596
  ]
  "baz" => array:2 [
    "elapsed" => 3.0001420974731
    "percent" => 0.15789085505934
  ]
]
uskup
sumber
13

PECL XHPROF juga terlihat menarik. Ini memiliki antarmuka HTML yang dapat diklik untuk melihat laporan dan dokumentasi yang cukup mudah . Saya belum mengujinya.

Josef Sábl
sumber
Sepertinya itu tidak mendapatkan banyak cinta. Pembaruan terakhir pada tahun 2009, tidak ada paket PEAR untuk 5,3, 5,4 dan seterusnya ...
dland
1
Facebook membuat garpu dengan dukungan melalui php 5.5 github.com/facebook/xhprof
borkencode
Periksa garpu ini juga yang mengusulkan beberapa penyesuaian tambahan: github.com/preinheimer/xhprof
Fedir RYKHTIK
xhprof.io menyediakan GUI untuk data yang dikumpulkan menggunakan XHProf, serta kemampuan untuk menyimpan data dalam database untuk tujuan analisis historis. Saya adalah penulis implementasi yang terakhir.
Gajus
10

Saya suka menggunakan phpDebug untuk profil. http://phpdebug.sourceforge.net/www/index.html

Ini menghasilkan semua waktu / penggunaan memori untuk SQL apa pun yang digunakan serta semua file yang disertakan. Jelas, ini bekerja paling baik pada kode yang diabstraksi.

Untuk fungsi dan profil kelas saya hanya akan menggunakan microtime()+ get_memory_usage()+ get_peak_memory_usage().

Eric Lamb
sumber
7

Saya menantang untuk mencoba BlackFire .

Ada virtualBox ini yang saya kumpulkan menggunakan puphpet , untuk menguji kerangka kerja php yang berbeda yang berasal dari BlackFire, silakan garpu dan / atau distribusikan jika diperlukan :)

https://github.com/webit4me/PHPFrameworks

Ali
sumber
6

Untuk pembandingan, seperti pada contoh Anda, saya menggunakan paket Benchmark pir . Anda menetapkan spidol untuk diukur. Kelas ini juga menyediakan beberapa pembantu presentasi, atau Anda dapat memproses data sesuai keinginan Anda.

Saya sebenarnya membungkusnya dengan kelas lain dengan metode __destruct. Ketika skrip keluar, output dicatat melalui log4php ke syslog, jadi saya punya banyak data kinerja untuk bekerja.

Gary Richardson
sumber
3

XDebug tidak stabil dan tidak selalu tersedia untuk versi php tertentu. Sebagai contoh pada beberapa server saya masih menjalankan php-5.1.6, - itulah yang datang dengan RedHat RHEL5 (dan btw masih menerima pembaruan untuk semua masalah penting), dan XDebug baru-baru ini bahkan tidak dapat dikompilasi dengan php ini. Jadi saya berakhir dengan beralih ke DBG debugger Pembandingan php- nya menyediakan waktu untuk fungsi, metode, modul dan bahkan garis.

pengguna2221743
sumber
2

Anda semua harus memeriksa profiler php baru ini.

https://github.com/NoiseByNorthwest/php-spx

Ini mendefinisikan kembali cara bagaimana profiler php mengumpulkan dan menyajikan hasilnya. Alih-alih hanya menampilkan total jumlah panggilan fungsi tertentu dan total waktu yang dihabiskan untuk mengeksekusinya - PHP-SPX menyajikan seluruh garis waktu eksekusi permintaan dengan cara yang mudah dibaca. Di bawah ini adalah layar GUI yang disediakannya.

masukkan deskripsi gambar di sini

Jacek Dziurdzikowski
sumber