วิธีที่ง่ายที่สุดในการสร้างโปรไฟล์สคริปต์ PHP


289

วิธีที่ง่ายที่สุดในการสร้างโปรไฟล์สคริปต์ PHP คืออะไร

ฉันชอบที่จะแก้ไขบางสิ่งบางอย่างที่แสดงให้ฉันเห็นว่าการเรียกใช้ฟังก์ชั่นทั้งหมดและระยะเวลาที่พวกเขาใช้ไป แต่ฉันก็โอเคที่จะทำหน้าที่เฉพาะเจาะจง

ฉันพยายามทดลองด้วยฟังก์ชั่นmicrotime :

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

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

แต่บางครั้งก็ให้ผลลัพธ์เชิงลบ รวมทั้งปัญหาในการโรยรหัสของฉัน


7
เฮ้มาร์คตรวจสอบความคิดเห็นนี้เพื่อช่วยคุณแก้ปัญหาความคิดเห็นเชิงลบ: ro.php.net/manual/en/function.microtime.php#99524
Mina

16
ความคิดเห็นที่เชื่อมโยงกับโดย @Midiane ไม่สมเหตุสมผล หากดูเหมือนว่าจะแก้ปัญหาของผู้วิจารณ์ก็ต้องเป็นเรื่องบังเอิญ เพียงแค่ใช้microtime()จะนำไปสู่การแสดงออกบางครั้งการประเมินที่ชอบ: ซึ่งจะประเมินเช่น:"0.00154800 1342892546" - "0.99905700 1342892545" 0.001548 - 0.999057คุณสามารถใช้microtime( TRUE )เพื่อหลีกเลี่ยงปัญหาดังกล่าวโดย @luka
JMM

คำตอบ:


104

PECL APDส่วนขยายจะใช้เป็นดังนี้

<?php
apd_set_pprof_trace();

//rest of the script
?>

pprofpหลังจากแยกไฟล์ที่สร้างขึ้นโดยใช้

ตัวอย่างผลลัพธ์:

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

คำเตือน: รุ่นล่าสุดของ APD คือวันที่ 2004 ส่วนขยายจะไม่ได้รับการบำรุงรักษาอีกต่อไปและมีปัญหาด้านความสามารถในการใช้งานต่างๆ (ดูความคิดเห็น)


19
ส่วนขยาย APD ใช้งานไม่ได้กับ php 5.4
Skynet

ในการตอบโต้กับผู้ใช้ 457015 ฉันสามารถทำให้เว็บไซต์ทำงานด้วย wordpress 3.8.1 และ PHP 5.3.10 และดูเหมือนว่าจะทำงานได้ดี
Supernovah

1
@Supernovah ผู้ใช้ 457015 พูดว่า PHP 5.4 เขาไม่ได้บอกว่ามันใช้งานไม่ได้กับ PHP 5.3
แมกนัส

@ user1420752 ฉันใช้ 5.3.27 และมันก็ไม่ทำงานเช่นกัน ฉันได้รับข้อผิดพลาดของฟังก์ชันที่ไม่ได้กำหนด
Fractaly

2
APD รุ่นล่าสุดมาจากปี 2004 (!) มันไม่ทำงานกับ PHP 7 เมื่อพยายามติดตั้งสำหรับ PHP 5 ด้วยpecl install apdจะให้ข้อความแสดงข้อผิดพลาดเกี่ยวกับ "config.m4" ดูเหมือนว่าคุณจะต้องติดตั้งจากแหล่งซึ่งฉันยังไม่ได้ลอง อย่างจริงจังไม่มีเครื่องมือสร้างโปรไฟล์ CLI ที่ทันสมัยและทันสมัยสำหรับ PHP ที่ติดตั้งด้วย Homebrew ต้องการการตั้งค่าขั้นต่ำและให้ผลลัพธ์ที่มนุษย์อ่านได้ง่ายหรือไม่
outrin

267

คุณต้องการxdebugฉันคิดว่า ติดตั้งบนเซิร์ฟเวอร์เปิดใช้งานปั๊มผลลัพธ์ผ่านkcachegrind (สำหรับ linux) หรือwincachegrind (สำหรับ windows) และมันจะแสดงแผนภูมิสวย ๆ ที่แสดงรายละเอียดเวลาที่แน่นอนจำนวนและการใช้หน่วยความจำ (แต่คุณจะ ต้องการส่วนขยายอื่นสำหรับสิ่งนั้น)

มันสั่นสะเทือนอย่างจริงจัง: D


6
ฉันพบสิ่งนี้ง่ายต่อการใช้งานมากกว่าโซลูชัน APD แต่อาจเป็นเพราะเหตุผลบางอย่าง APD ไม่ได้รวบรวมอย่างถูกต้องในระบบของฉัน ชาร์ตของ kcachegrind ก็สวยเหมือนที่สัญญาไว้
wxs

1
@EvilPuppetMaster คุณต้องรวบรวม php ด้วย --enable-memory-limit หรือใช้ php เวอร์ชันที่ทันสมัยกว่า ดูxdebug.org/docs/basic#xdebug_memory_usage
mercutio

52
xdebug + webgrind อย่างรวดเร็วกลายเป็นอาวุธที่ฉันเลือกสำหรับการทำโปรไฟล์ที่ง่ายและรวดเร็ว code.google.com/p/webgrind
xkcd150

6
xdebug + xdebug_start_trace () + xdebug_stop_trace () = ชนะ
quano

3
นี่เป็นเรื่องง่ายมากที่จะทำงานกับ Windows ด้วย XAMPP มี netbeans ที่ตั้งค่าไว้สำหรับ xdebug แล้ว สิ่งเดียวที่คุณต้องทำคือเปลี่ยนการตั้งค่า xdebug ใน php.ini เป็น xdebug.profiler_output_name = "cachegrind.out.% t-% s" มิฉะนั้นจะไม่มีการสร้างเอาต์พุต ต้องรีสตาร์ท apache
เริ่มต้น

97

ไม่จำเป็นต้องใช้ส่วนขยายเพียงใช้ทั้งสองฟังก์ชั่นเพื่อการทำโปรไฟล์อย่างง่าย

// 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>";
}

นี่คือตัวอย่างการเรียก prof_flag () พร้อมคำอธิบายที่แต่ละจุดตรวจและ prof_print () ที่ท้าย:

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();

ผลลัพธ์มีดังนี้:

เริ่มต้น
   0.004303
เชื่อมต่อกับฐานข้อมูล
   0.003518
ดำเนินการค้นหา
   0.000308
ดึงข้อมูล
   0.000009
ปิดฐานข้อมูล
   0.000049
เสร็จสิ้น


37

ข้ามการโพสต์การอ้างอิงของฉันจาก SO Documentation เบต้าซึ่งกำลังออฟไลน์

การทำโปรไฟล์ด้วย XDebug

ส่วนขยายของ PHP ที่ชื่อว่า Xdebug นั้นพร้อมให้ความช่วยเหลือในการทำโปรไฟล์แอปพลิเคชัน PHPรวมถึงการดีบักรันไทม์ เมื่อรัน profiler เอาต์พุตจะถูกเขียนไปยังไฟล์ในรูปแบบไบนารีที่เรียกว่า "cachegrind" แอปพลิเคชั่นพร้อมใช้งานในแต่ละแพลตฟอร์มเพื่อวิเคราะห์ไฟล์เหล่านี้ ไม่มีการเปลี่ยนแปลงรหัสแอปพลิเคชันที่จำเป็นในการทำโปรไฟล์นี้

หากต้องการเปิดใช้งานการทำโปรไฟล์ให้ติดตั้งส่วนขยายและปรับการตั้งค่า php.ini ลีนุกซ์บางรุ่นมาพร้อมกับแพ็คเกจมาตรฐาน (เช่นphp-xdebugแพ็คเกจของ Ubuntu ) ในตัวอย่างของเราเราจะเรียกใช้โปรไฟล์โดยเลือกตามพารามิเตอร์คำขอ สิ่งนี้ช่วยให้เราสามารถตั้งค่าให้คงที่และเปิดใช้งาน profiler ได้ตามต้องการ

# 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"

ถัดไปใช้เว็บไคลเอ็นต์เพื่อส่งคำขอไปยัง URL แอปพลิเคชันของคุณที่คุณต้องการทำโปรไฟล์เช่น

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

เมื่อหน้าประมวลผลมันจะเขียนไปยังไฟล์ที่มีชื่อคล้ายกับ

/tmp/cachegrind.out.12345

โดยค่าเริ่มต้นจำนวนในชื่อไฟล์คือรหัสกระบวนการที่เขียนมัน นี่คือการกำหนดค่าด้วยการxdebug.profiler_output_nameตั้งค่า

โปรดทราบว่ามันจะเขียนหนึ่งไฟล์สำหรับแต่ละคำขอ / กระบวนการ PHP ที่ดำเนินการ ตัวอย่างเช่นหากคุณต้องการวิเคราะห์การโพสต์ฟอร์มหนึ่งโปรไฟล์จะถูกเขียนเพื่อขอ GET เพื่อแสดงแบบฟอร์ม HTML พารามิเตอร์ XDEBUG_PROFILE จะต้องถูกส่งผ่านไปยังคำขอ POST ที่ตามมาเพื่อวิเคราะห์คำขอที่สองซึ่งประมวลผลแบบฟอร์ม ดังนั้นเมื่อการทำโปรไฟล์บางครั้งการเรียกใช้ curl เพื่อ POST แบบฟอร์มได้ง่ายขึ้น

การวิเคราะห์ผลลัพธ์

เมื่อเขียนแคชรายละเอียดสามารถอ่านได้โดยโปรแกรมดังกล่าวเป็นKCachegrindหรือWebgrind PHPStorm ซึ่งเป็น PHP IDE ยอดนิยมสามารถแสดงข้อมูลการทำโปรไฟล์นี้ได้

KCachegrind

ตัวอย่างเช่น KCachegrind จะแสดงข้อมูลรวมถึง:

  • ฟังก์ชั่นการดำเนินการ
  • เวลาโทรทั้งตัวเองและรวมของฟังก์ชั่นการโทรตามมา
  • จำนวนครั้งที่เรียกใช้แต่ละฟังก์ชัน
  • กราฟการโทร
  • ลิงก์ไปยังซอร์สโค้ด

สิ่งที่ควรมองหา

เห็นได้ชัดว่าการปรับประสิทธิภาพนั้นมีความเฉพาะเจาะจงกับกรณีการใช้งานของแต่ละแอปพลิเคชัน โดยทั่วไปแล้วมันเป็นเรื่องดีที่จะมองหา:

  • การเรียกซ้ำไปยังฟังก์ชันเดียวกันที่คุณไม่คาดหวังให้เห็น สำหรับฟังก์ชั่นที่ประมวลผลและค้นหาข้อมูลอาจเป็นโอกาสสำคัญสำหรับแอปพลิเคชันของคุณในการแคช
  • ฟังก์ชั่นที่ทำงานช้า แอปพลิเคชันใช้เวลาส่วนใหญ่อยู่ที่ไหน ผลตอบแทนที่ดีที่สุดในการปรับแต่งประสิทธิภาพคือมุ่งเน้นไปที่ส่วนต่างๆของแอปพลิเคชันซึ่งใช้เวลามากที่สุด

หมายเหตุ : Xdebug และโดยเฉพาะอย่างยิ่งคุณลักษณะการทำโปรไฟล์ของมันนั้นใช้ทรัพยากรอย่างมากและทำให้การประมวลผลของ PHP ช้าลง ขอแนะนำให้ไม่เรียกใช้สิ่งเหล่านี้ในสภาพแวดล้อมเซิร์ฟเวอร์ที่ใช้งานจริง


3
การเพิ่มลงในรายการเครื่องมือสำหรับการวิเคราะห์แคชโปรไฟล์: PhpStorm ยังมีเครื่องมือสำหรับการดูตัวอย่างแคชโปรไฟล์
peterchaula

1
@ peter ฉันลืม PHPStorm มีคุณสมบัตินั้น ฉันได้เพิ่มมันพร้อมลิงค์ไปยังเอกสารประกอบ ขอบคุณ!
Matt S

มีวิธีใดที่จะได้รับข้อความ (ไม่ใช่ GUI) รายงานโดยตรงบนเซิร์ฟเวอร์?
Alexander Shcheblikin

1
@ Mark ทำเครื่องหมายว่านี่เป็นคำตอบได้ไหม คำตอบปัจจุบันล้าสมัยแม้ว่าจะโพสต์และไม่ได้ทำงานเป็นเวลาหลายปีการทำงานนี้และฉันรู้ว่าไม่มีวิธีที่ดี
Mawg กล่าวว่าคืนสถานะโมนิก้า

24

หากการลบ microtimes ให้ผลลัพธ์เชิงลบให้คุณลองใช้ฟังก์ชันด้วยอาร์กิวเมนต์true( microtime(true)) ด้วยtrueฟังก์ชั่นส่งกลับลอยแทนสตริง (เช่นถ้ามันถูกเรียกว่าไม่มีข้อโต้แย้ง)


24

สุจริตฉันจะยืนยันว่าการใช้ NewRelic สำหรับการทำโปรไฟล์นั้นดีที่สุด

มันเป็นส่วนเสริมของ PHP ซึ่งดูเหมือนจะไม่ทำให้การรันไทม์ลดลง แต่อย่างใดและพวกเขาทำการตรวจสอบให้คุณ ในรุ่นแพงพวกเขาอนุญาตให้เจาะลึก (แต่เราไม่สามารถซื้อรูปแบบการกำหนดราคาของพวกเขา)

อย่างไรก็ตามถึงแม้จะมีแผนฟรี / มาตรฐานก็ชัดเจนและเรียบง่ายที่ส่วนใหญ่ของผลไม้แขวนอยู่ต่ำ ฉันก็ชอบที่มันสามารถให้ความคิดกับคุณเกี่ยวกับการโต้ตอบของ DB ได้เช่นกัน

สกรีนช็อตของหนึ่งในอินเตอร์เฟสเมื่อทำโปรไฟล์


16
ของใหม่ที่ระลึกดูดีอย่างแน่นอน อย่างไรก็ตาม "การเปิดเผยข้อมูลแอปพลิเคชันของคุณ" เป็นส่วนหนึ่งของนโยบายความเป็นส่วนตัวของพวกเขามันทำให้ฉันทันที อิมโฮการแบ่งปันซอร์สโค้ดที่เป็นกรรมสิทธิ์กับบุคคลที่สามนั้นมากเกินไป
Cengiz สามารถ

8
ไม่กระโชกกับการป้องกันที่นี่ แต่ดูเหมือนว่า "Application Data" เป็นเพียงข้อมูลประสิทธิภาพและข้อมูลการกำหนดค่าระบบไม่ใช่ซอร์สโค้ดแอปพลิเคชันของคุณ
David Shields

Fir ของที่ระลึกใหม่ของฉันแสดง "WebTransaction" ของฉันเป็น 99% ของเวลาและไม่มีบัญชีโปรสำหรับ "ApplicationTraces"
Karthik T

1
ลองลงทะเบียนได้ที่: newrelic.com/rackspace <ควรให้ "มาตรฐาน" แก่คุณฟรี
zeroasterisk

16

การทำโปรไฟล์ของคนจนไม่จำเป็นต้องใช้ส่วนขยาย รองรับโปรไฟล์ที่ซ้อนกันและร้อยละของทั้งหมด:

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;
}

ตัวอย่าง:

<?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());

อัตราผลตอบแทน:

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
  ]
]

13

PECL XHPROF ก็ดูน่าสนใจเช่นกัน มันมีอินเตอร์เฟซ HTML คลิกได้สำหรับรายงานการดูและตรงไปตรงสวยเอกสาร ฉันยังไม่ได้ทดสอบเลย


ดูเหมือนว่ามันจะไม่ได้รับความรักมากนัก อัปเดตครั้งล่าสุดในปี 2009 ไม่มีแพคเกจ PEAR สำหรับ 5.3, 5.4 ขึ้นไป ...
dland

1
Facebook สร้างทางแยกด้วยการสนับสนุนผ่าน php 5.5 github.com/facebook/xhprof
borkencode

ตรวจสอบส้อมนี้ด้วยซึ่งเสนอการปรับเปลี่ยนเพิ่มเติมบางอย่าง: github.com/preinheimer/xhprof
Fedir RYKHTIK

xhprof.ioจัดเตรียม GUI สำหรับข้อมูลที่รวบรวมโดยใช้ XHProf เช่นเดียวกับความสามารถในการจัดเก็บข้อมูลในฐานข้อมูลเพื่อการวิเคราะห์เชิงประวัติ ฉันเป็นผู้ประพันธ์การติดตั้งระบบหลัง
Gajus

10

ฉันชอบใช้ phpDebug สำหรับการทำโปรไฟล์ http://phpdebug.sourceforge.net/www/index.html

มันแสดงผลการใช้เวลา / หน่วยความจำทั้งหมดสำหรับ SQL ที่ใช้รวมถึงไฟล์ที่รวมทั้งหมด เห็นได้ชัดว่ามันทำงานได้ดีที่สุดในรหัสที่เป็นนามธรรม

สำหรับฟังก์ชั่นและชั้น profiling ฉันเพิ่งจะใช้microtime()+ +get_memory_usage()get_peak_memory_usage()



6

สำหรับการเปรียบเทียบเช่นในตัวอย่างของคุณฉันใช้ลูกแพร์เบนช์มาร์กแพกเกจคุณตั้งค่าเครื่องหมายสำหรับการวัด ชั้นเรียนยังมีผู้ช่วยงานนำเสนอไม่กี่คนหรือคุณสามารถประมวลผลข้อมูลตามที่เห็นสมควร

จริง ๆ แล้วฉันมีมันห่อในชั้นเรียนอื่นด้วยวิธีการทำลาย __ เมื่อออกจากสคริปต์เอาต์พุตจะถูกบันทึกผ่าน log4php ไปยัง syslog ดังนั้นฉันจึงมีข้อมูลประสิทธิภาพมากมายให้ใช้งาน


3

XDebug ไม่เสถียรและไม่พร้อมใช้งานสำหรับรุ่น php โดยเฉพาะ ตัวอย่างเช่นในบางเซิร์ฟเวอร์ฉันยังคงเรียกใช้ php-5.1.6 - เป็นสิ่งที่มาพร้อมกับ RedHat RHEL5 (และ btw ยังคงได้รับการอัปเดตสำหรับปัญหาที่สำคัญทั้งหมด) และ XDebug เมื่อเร็ว ๆ นี้ไม่ได้รวบรวม php นี้ ดังนั้นฉันก็เลยเปลี่ยนมาใช้ดีบักเกอร์ DBG การเปรียบเทียบมาตรฐานของPHP นั้นให้เวลาสำหรับฟังก์ชั่นวิธีการโมดูลและแม้กระทั่งเส้น


2

คุณควรตรวจสอบ php profiler ใหม่นี้อย่างแน่นอน

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

มันนิยามวิธีการรวบรวมโปรไฟล์ของ php และนำเสนอผลลัพธ์ แทนที่จะเอาท์พุทจำนวนการเรียกฟังก์ชั่นเฉพาะทั้งหมดและเวลาที่ใช้ในการดำเนินการทั้งหมด - PHP-SPX นำเสนอระยะเวลาทั้งหมดของการดำเนินการร้องขอในวิธีที่อ่านได้อย่างสมบูรณ์ ด้านล่างเป็นหน้าจอของ GUI ที่มีให้

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.