BioLawCom.De » Blog » เขียนโปรแกรม » PHP Profiling and Optimisation with Xdebug

PHP Profiling and Optimisation with Xdebug

imageเวลาผมเขียนโปรแกรมจะเป็นพวกชอบรีด คือ ต้องรีด Performance ของโปรแกรมออกมาให้ได้มากที่สุด แม้ว่าในบางครั้ง Performance Optimisation จะหมายถึงโค้ดที่ดูแลยากขึ้น แต่ในบางครั้งการแก้ไขโค้ดเพียงเล็กน้อยก็ อาจทำให้โปรแกรมทำงานเร็วขึ้นอย่างเห็นได้ชัด หากเลือกได้ ทุกคนคงเลือกอย่างหลัง เครื่องมือสำคัญสำหรับ Performance Optimisation คือ Profiling Tools โดย Profiling Tools จะเป็นตัวบอกเราว่า ส่วนต่าง ๆ ของโปรแกรมใช้เวลาในการประมวลผลเท่าไร หรือ Profiling Tools บางตัวอาจบอกเราได้ด้วย ว่าส่วนต่าง ๆ ของโปรแกรมใช้หน่วยความจำไปเท่าไร

ส่วนมากแล้วภาษาเขียนโปรแกรมหรือเครื่องมือที่เป็น OpenSource มักไม่มี Profiling Tools ดี ๆ ใช้ง่าย ๆ ให้ใช้งานอย่างเครื่องมือเชิงพาณิชย์ราคาแพง ๆ (เช่น ใน MATLAB มี Profiling Tools ที่สุดยอดมาก ) แต่ในภาษาเขียนโปรแกรม PHP มี Profiling Tools ที่เป็น OpenSource เจ๋ง ๆ และใช้งานง่าย อย่าง Xdebug ซึ่งนอกจากจะใช้เป็น Profiling Tools แล้ว ยังใช้เป็นเครื่องมือสำหรับ Debug ได้อีกด้วย แต่ในครั้งนี้ผมจะเน้นการนำ Xdebug มาใช้งานในลักษณะ Profiling Tools

Xdebug เป็น Extension สำหรับ PHP ที่ต้องทำงานร่วมกับ Apache และ mod_php สำหรับคนที่ใช้ Windows สามารถ ดาวน์โหลด Xdebug และติดตั้งใช้งานร่วมกับ mod_php ได้ สำหรับคนที่ใช้งาน Ubuntu เพียงแค่พิมพ์คำสั่ง

sudo apt-get install php5-xdebug

ก็สามารถใช้งาน Xdebug ร่วมกับ mod_php ได้ทันที ...

เขียนโปรแกรม เขียนโปรแกรม

bow_der_kleine bow_der_kleine

สิ่งแรกที่เปลี่ยนแปลงไปอย่างเห็นได้ชัด หลังจากติดตั้ง Xdebug คือ Error Messages ที่เปลี่ยนแปลงไป จากเดิม Error Messages ของ PHP จะโผล่ขึ้นมาเพียงสั้น ๆ หนึ่งบรรทัด ว่าเกิดอะไรขึ้นที่ไหน แต่ด้วย Xdebug ก็จะมีรายละเอียดต่าง ๆ เกี่ยวกับข้อผิดพลาดที่เกิดขึ้นให้เราได้รู้อะไรมากขึ้น ดังรูปตัวอย่างข้างล่าง

image

หลังจากที่ติดตัั้ง Xdebug เรียบร้อยแล้ว เรายังไม่สามารถใช้งาน Profiling ของ Xdebug ได้ทันที เพราะ Profiling จะทำให้โปรแกรมที่เราเขียนขึ้นทำงานช้ากว่าปกติ ดังนั้น เราจึงควรเลือกใช้งาน Profiling ในกรณีที่จำเป็นเท่านั้น โดยขั้นตอนการเปิดใช้งาน Profiling ก็มีง่าย ๆ ดังนี้ครับ

1 แก้ไขไฟล์ php.ini (ใน Ubuntu อยู่ที่ /etc/php5/apache2/php.ini) โดยเพิ่มสองบรรทัดนี้ลงไป

xdebug.profiler_enable = 1

xdebug.profiler_output_dir = /tmp/

โดย xdebug.profiler_output_dir คือไดเรคทอรี่ที่ใช้บันทึกผลที่ได้จาก Profiling ในตัวอย่างผมเลือกใช้ /tmp/ เพราะหลังจากปิดเครื่องไฟล์ที่ถูกบันทึกจะได้ถูกลบไปแบบอัตโนมัติ

2 restart apache ใน Ubuntu ให้ใช้คำสั่งต่อไปนี้ครับ

sudo /etc/init.d/apache2 restart

หลังจากนั้นเราก็เรียกใช้งานหน้าเวบที่เราเขียนด้วย PHP ตามปกติ ซึ่งเราจะไม่เห็นข้อแตกต่างอะไรที่ชัดเจนนัก นอกจากระยะเวลาในการประมวลผลที่นานขึ้น นั่นก็เพราะว่า Xdebug ต้องประมวลผลการ Profiling และบันทึกผลที่ได้ไว้ในไดเรคทอรี่ที่เรากำหนด

หลังจากที่ Xdebug ทำหน้าที่ในการ Profiling เรียบร้อยแล้ว ก็มถึงขั้นตอนในการดูการผลที่ได้จาก Profiling โดยไฟล์ที่ถูกบันทึกลงไปในไดเรคทอรี่ที่เรากำหนดนั้นจะเป็น text file ที่ดูแล้วไม่ค่อยรู้เรื่อง ต้องใช้เครื่องมืออีกตัวสำหรับ vitualization โดยใน Windows มีโปรแกรมเก่ากรุอย่าง WinCachegrind ให้เลือกใช้งาน ส่วนบน Linux มี KCachegrind สำหรับคนใช้ Ubuntu สามารถติดตั้งด้วยคำสั่ง

sudo apt-get install kcachegrind

เมื่อติดตั้ง KCachegrind เรียบร้อยแล้ว ก็เปิดโปรแกรม KCachegrind (ใน Ubuntu อยู่ที่ Applications => Programming => KCachegrind) แล้วเปิดไฟล์ที่ได้จาก Profiling ของ Xdebug (จากตัวอย่างไฟล์ที่ได้คือ /tmp/cachegrind.out.*) และหากไม่มีอะไรผิดพลาด KCachegrind หลังจากเปิดไฟล์จะมีหน้าตาประมาณนี้

image

ในหน้าต่างทางซ้ายก็จะเป็นรายชื่อฟังก์ชั่น ที่ใช้เวลาในการประมวลผลมากที่สุด เรียงลำตับจากมากไปหาน้อย พร้อมจำนวนครั้งที่ฟังก์ชั่นถูกเรียก ส่วนทางขวาก็จะเป็นกราฟแบบต่าง ๆ (ตัวอย่าง 1 , ตัวอย่าง 2) ซึ่งเป็นอะไรที่ผมรู้สึกว่ามันเจ๋งดี เพราะดูแล้วเข้าใจง่าย รู้ได้ทันทีว่าฟังก์ชันไหนเรียกใช้ฟังก์ชันไหน กี่ครั้ง รวมทั้งหมดใช้เวลาในการประมวลผลเท่าไร และทำให้ผมรู้ว่า require_once เป็นอะไรที่ทำให้โปรแกรมทำงานช้า (ว่ากันว่า include เร็วกว่า require เร็วกว่า include_once เร็วกว่า require_once) เมื่อเปลี่ยนจาก require_once มาเป็น include โปรแกรมก็ทำงานเร็วขึ้นมาประมาณ 15% แต่ต้องใช้หน่วยความจำเพิ่มขึ้นจาก 4.3MB เป็น 5.4MB

image

โปรแกรมใช้เวลาไปกับ require_once ประมาณ 5% ซึ่งไม่ได้ทำอะไรเลย นอกจากโหลดโมดูลมาเก็บไว้

ข้อมูลอย่างนึง ที่เราไม่สามารถใช้ KCachegrind ดูได้ คือปริมาณการใช้หน่วยความจำในส่วนต่าง ๆ ของโปรแกรม ในกรณีนี้เราต้องใช้เทคนิคอย่างอื่นของ Xdebug นั่นคือ การเรียกใช้ฟังก์ชัน  xdebug_start_tracec และ  xdebug_stop_trace ร่วมกับโค้ดของโปรแกรม PHP ยกตัวอย่างเช่น

<?php
xdebug_start_trace("/tmp/xdebug_trace"); # บันทึกผลที่ได้ลงในไฟล์ tmp/xdebug_trace.txt
 
do_something();
 
xdebug_stop_trace(); # หยุดการ trace
?>
plain code

ผลที่ได้จาก xdebug_start_tracec และ  xdebug_stop_trace ในตัวอย่างจะถูกบันทึกไว้ในไฟล์ /tmp/xdebug_trace.xt ซึ่งเราสามารถใช้ Text Editor เปิดดูรายละเอียดต่าง ๆ เกี่ยวกับการทำงานของโปรแกรมได้ ข้อควรระวังคือ ขนาดของไฟล์ที่ได้ จะแปรผันตรงกับขั้นตอนการทำงานของโปรแกรมที่อยู่ระหว่าง xdebug_start_tracec และ  xdebug_stop_trace ดังนั้น ในโปรแกรมที่ซับซ้อนมาก ๆ อาจทำให้เกิดปัญหาเกี่ยวกับ IO ของระบบได้

นอกจากเราจะใช้ Xdebug สำหรับงาน Profiling และ Optimisation แล้ว เรายังสามารถนำมาใช้เพื่อทำความเข้าใจการทำงานของโปรแกรมต่าง ๆ ที่มีความซับซ้อนได้อีกด้วย แทนที่จะนั่งอ่านโค้ดทีละบรรทัด ก็ดูเป็น Diagram ที่ทำความเข้าใจได้ง่ายกว่า ถือว่ามีประโยชน์มากทีเดียว

ข้อมูลเพิ่มเติม Xdebug Documentation, Understanding PHP code better with Xdebug

15 Feb 09 | by | tags เขียนโปรแกรม PHP Optimisation Profiling Xdebug

read 1083

<<ผลิตเพื่อขายใคร ? || สิทธิส่วนบุคคล บนโลกเสมือน>>

crucifier

ขอบคุณเหลือเกินสำหรับตัวช่วยดีๆ แบบนี้ครับ ผมพยายามหามานาน แต่ไม่เจอที่ใช้ได้จริงเลย

ถ้ามีเวลาก็จะ optimize งานตัวเองบ้าง จะได้ประมวลผลได้เร็วและมีประสิทธิภาพมากขึ้นขึ้น ตอนนี้ขอแค่ "ทำงานเร็ว" ไปก่อน ปั่นงานแลกเศษเงิน ไม่มี bug ผมก็พอใจแล้วตอนนี้

15 Feb 09

vetan

นับถือเป็นลูกพี่อีกคน  อยากให้เขียนบ่อยๆ รออ่านอยู่ครับ

17 Feb 09

ความคิดเห็น (click here to comment)

Search

Navigation

ความเคลื่อนไหว

รวมลิงก์น่าสนใจ

Login

name password

ลืมรหัสผ่าน