ฉันจะวัดความเร็วของโค้ดที่เขียนด้วย PHP ได้อย่างไร? [ปิด]


118

ฉันจะบอกได้อย่างไรว่าคลาสใดของจำนวนมาก (ซึ่งทั้งหมดทำงานเหมือนกัน) ดำเนินการเร็วกว่า มีซอฟต์แวร์วัดผลหรือไม่

คำตอบ:


195

คุณมี(อย่างน้อย)สองวิธี:

สิ่งที่ค่อนข้าง "ไร้เดียงสา" คือการใช้ microtime (จริง) ก่อนและหลังโค้ดส่วนหนึ่งเพื่อดูว่าเวลาผ่านไปเท่าไรในระหว่างการดำเนินการ คำตอบอื่น ๆ บอกอย่างนั้นและยกตัวอย่างไปแล้วดังนั้นฉันจึงไม่ต้องพูดอะไรอีกมาก

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

อะไรทำนองนี้ดังนั้นหากคุณต้องการทราบว่าการต่ออนุกรมอาร์เรย์ใช้เวลานานเท่าใด:

$before = microtime(true);

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

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

ไม่สมบูรณ์แบบ แต่มีประโยชน์และใช้เวลาไม่มากในการตั้งค่า



วิธีแก้ปัญหาอื่น ๆ ที่ใช้งานได้ดีหากคุณต้องการระบุว่าฟังก์ชันใดใช้เวลานานในสคริปต์ทั้งหมดคือการใช้:

  • Xdebugขยายเพื่อสร้างข้อมูลโปรไฟล์สำหรับสคริปต์
  • ซอฟต์แวร์ที่อ่านข้อมูลการทำโปรไฟล์และนำเสนอสิ่งที่คุณอ่านได้ ฉันรู้สามข้อ:
    • Webgrind ; เว็บอินเตอร์เฟส ควรทำงานบนเซิร์ฟเวอร์ Apache + PHP ใด ๆ
    • WinCacheGrind ; บน windows เท่านั้น
    • KCacheGrind ; อาจเป็นเพียง Linux และ linux เท่านั้น นั่นคือสิ่งที่ฉันชอบ btw

ในการรับไฟล์โปรไฟล์คุณต้องติดตั้งและกำหนดค่า Xdebug ดูที่หน้าProfiling PHP Scriptsของเอกสาร

สิ่งที่ฉันทำโดยทั่วไปไม่ได้เปิดใช้งาน profiler ตามค่าเริ่มต้น(มันสร้างไฟล์ที่ค่อนข้างใหญ่และทำให้สิ่งต่างๆช้าลง)แต่ใช้ความเป็นไปได้ในการส่งพารามิเตอร์ที่เรียกว่าXDEBUG_PROFILEGET data เพื่อเปิดใช้งานการสร้างโปรไฟล์สำหรับหน้าที่ฉันต้องการเท่านั้น
ส่วนที่เกี่ยวข้องกับการทำโปรไฟล์ของ php.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

(อ่านเอกสารสำหรับข้อมูลเพิ่มเติม)

ภาพหน้าจอนี้มาจากโปรแกรม C ++ ใน KcacheGrind: (ที่มา: sourceforge.net )คุณจะได้สิ่งที่เหมือนกันทุกประการกับสคริปต์ PHP ;-) (ด้วย KCacheGrind ฉันหมายถึง WinCacheGrind ไม่ดีเท่า KCacheGrind ... )http://kcachegrind.sourceforge.net/html/pics/KcgShot3Large.gif



นี้ช่วยให้คุณได้รับมุมมองที่ดีของสิ่งที่ต้องใช้เวลาในการประยุกต์ใช้ของคุณ - และบางครั้งมันก็แน่นอนช่วยในการค้นหาฟังก์ชั่นที่มีการชะลอตัวลงทุกอย่าง ^^

โปรดทราบว่า Xdebug จะนับเวลาที่ CPU ใช้โดย PHP เมื่อ PHP กำลังรอคำตอบจากฐานข้อมูล (เช่น) มันไม่ทำงาน รอเท่านั้น ดังนั้น Xdebug จะคิดว่าคำขอ DB ใช้เวลาไม่นาน!
ควรทำโปรไฟล์บนเซิร์ฟเวอร์ SQL ไม่ใช่ PHP ดังนั้น ...


หวังว่านี่จะเป็นประโยชน์ :-)
ขอให้สนุก!


1
มีหน้าต่าง QCacheGrind อยู่ :-) sourceforge.net/projects/qcachegrindwin
François Breton

43

สำหรับสิ่งที่รวดเร็วฉันทำสิ่งนี้ (ใน PHP):

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

นอกจากนี้คุณยังสามารถใช้ Profiler เหมือนhttp://xdebug.org/


2
เพื่อความแม่นยำเพิ่มเติมฉันขอแนะนำให้ (ก) ใช้การวนซ้ำและการหาค่าเฉลี่ยของเวลาและ (b) ใช้ไฟล์แยกกันสำหรับแต่ละสิ่งที่คุณกำลังทดสอบ หากคุณมีการกำหนดเวลาหลายรายการในสคริปต์เดียวลำดับของพวกเขาอาจสร้างความแตกต่างได้ในบางครั้ง
แพะไม่พอใจ

9

ฉันได้สร้างคลาสจับเวลาง่ายๆแล้วอาจมีประโยชน์กับใครบางคน:

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

}

ใช้:

$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 

คุณพิมพ์ผิด: echoไม่ใช่$echo
SuN

9

อัปเดตปี 2020

เป็นเวลาหลายปีแล้วที่ฉันตอบคำถามนี้ครั้งสุดท้ายดังนั้นฉันจึงคิดว่าสิ่งนี้สมควรได้รับการอัปเดตเกี่ยวกับแนวนอน APM

  • Cisco ซื้อ AppDynamics และบัญชีฟรีตลอดไปที่พวกเขาเคยนำเสนอได้ถูกนำออกจากเว็บไซต์ของพวกเขา
  • NewRelic ได้ลดราคาจาก $ 149 / เดือน / โฮสต์เป็น $ 25 / เดือน / โฮสต์เพื่อแข่งขันกับผู้มาใหม่ในตลาด APM Datadog ซึ่งเสนอ $ 31 / เดือน / โฮสต์
  • คุณสมบัติ Datadog APM ยังคงเบาและเป็นที่ต้องการอย่างมาก อย่างไรก็ตามฉันเห็นว่าพวกเขาเสริมสร้างและปรับปรุงสิ่งเหล่านี้ตลอดทั้งปีหน้า
  • Dynatrace ซื้อ Ruxit ไปแล้ว ไม่มีอะไรน่าตกใจเพราะ Ruxit สร้างขึ้นโดยอดีตพนักงาน Dynatrace สิ่งนี้ทำให้ Dynatrace สามารถเปลี่ยนเป็นโมเดล SaaS ได้ดีขึ้น บอกลาไคลเอนต์ Java ที่มีขนาดใหญ่ได้หากคุณต้องการ
  • ตอนนี้มีตัวเลือกฟรี / โอเพ่นซอร์สเช่นกัน ชำระเงินApache Skywalkingซึ่งเป็นที่นิยมอย่างมากในประเทศจีนในบรรดา บริษัท เทคโนโลยีชั้นนำและPinPointซึ่งมีการสาธิตให้คุณทดลองใช้ก่อนติดตั้ง ทั้งสองอย่างนี้ต้องการให้คุณจัดการโฮสติ้งดังนั้นเตรียมพร้อมที่จะหมุนเครื่องเสมือนไม่กี่เครื่องและใช้เวลากับการติดตั้งและกำหนดค่า
  • ฉันไม่ได้ลองใช้โซลูชัน APM แบบโอเพนซอร์ซเหล่านี้ดังนั้นฉันจึงไม่สามารถแนะนำได้อย่างไรก็ตามฉันได้จัดการการปรับใช้โซลูชัน APM ทั้งหมดนี้เป็นการส่วนตัวสำหรับหลายองค์กรทั้งในองค์กรหรือบนคลาวด์สำหรับแอปพลิเคชันหลายร้อยรายการ / microservices ดังนั้นฉันสามารถพูดด้วยความมั่นใจคุณไม่สามารถผิดพลาดกับผู้ขายใด ๆ หากพวกเขาเหมาะสมกับใบเรียกเก็บเงินของคุณ


ตอบครั้งแรกเมื่อตุลาคม 2015

นี่คือคำตอบโดยตรงสำหรับคำถามของคุณ

มีซอฟต์แวร์วัดผลหรือไม่

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

ทำไมไม่ใช้เครื่องมือ Application Performance Monitoring (APM) ซึ่งสร้างมาเพื่อสิ่งนั้นและอื่น ๆ อีกมากมาย ตรวจสอบ NewRelic, AppDynamics, Ruxit (ทั้งหมดมีเวอร์ชันฟรี) เพื่อตรวจสอบเวลาดำเนินการการใช้ทรัพยากรปริมาณงานของทุกแอปพลิเคชันจนถึงระดับวิธีการ


6

หากคุณต้องการทดสอบประสิทธิภาพของเฟรมเวิร์กอย่างรวดเร็วคุณสามารถใส่ไฟล์index.php

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

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

ทุกครั้งที่คุณจะได้รับการดำเนินการในเวลามิลลิวินาที เนื่องจากไมโครวินาทีไม่มีประโยชน์มากเกินไปในการทดสอบเคสเฟรมเวิร์ก


5

ผมเคยใช้เมื่อเร็ว ๆ นี้ XHProf http://pecl.php.net/package/xhprof เดิมได้รับการพัฒนาโดย Facebook และมาพร้อมกับเว็บอินเตอร์เฟสที่ดี


4

ฉันต้องการแบ่งปันฟังก์ชันที่สร้างขึ้นเองกับคุณที่ฉันใช้เพื่อวัดความเร็วของฟังก์ชันที่มีอยู่สูงสุด 10 อาร์กิวเมนต์:

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;

}

ตัวอย่าง

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

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

ผลตอบแทน

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


3

Zend Studio ได้สร้างขึ้นเพื่อรองรับการสร้างโปรไฟล์โดยใช้ XDebug หรือ ZendDebugger มันจะกำหนดรายละเอียดรหัสของคุณบอกคุณว่าทุกฟังก์ชันใช้เวลานานแค่ไหน เป็นเครื่องมือที่ยอดเยี่ยมในการหาว่าคอขวดของคุณอยู่ที่ใด


1

คุณสามารถใช้สิ่งพื้นฐานเช่นการจัดเก็บการประทับเวลาหรือไมโครไทม์ () ก่อนและหลังการดำเนินการเพื่อคำนวณเวลาที่ต้องการ ทำได้ง่าย แต่ไม่ค่อยถูกต้อง บางทีทางออกที่ดีกว่าคือXdebugฉันไม่เคยทำงานด้วย แต่ดูเหมือนว่าจะเป็นดีบักเกอร์ / โปรไฟล์ PHP ที่รู้จักกันดีที่สุดที่ฉันสามารถหาได้

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