PHP 스크립트를 프로파일 링하는 가장 간단한 방법


289

PHP 스크립트를 프로파일 링하는 가장 쉬운 방법은 무엇입니까?

나는 모든 기능 호출의 덤프와 시간이 얼마나 걸렸는지를 보여주기를 원하지만 특정 기능 주위에 무언가를 넣는 것으로도 괜찮습니다.

마이크로 타임 기능을 실험 해 보았습니다 .

$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. @luka가 지적한microtime( TRUE ) 것처럼 문제를 피하기 위해 사용할 수 있습니다 .
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

user457015에 대한 레토르트에서 wordpress 3.8.1 및 PHP 5.3.10을 실행하는 웹 사이트에서 작동하도록 할 수 있었고 제대로 작동하는 것 같습니다.
Supernovah

1
@Supernovah, user457015는 PHP 5.4라고 말했습니다. 그는 PHP 5.3에서 고장 났다고 말하지 않았다.
magnus

@ user1420752 5.3.27을 실행 중이며 거기에서도 실행되지 않습니다. 정의되지 않은 함수 오류가 발생합니다.
Fractaly

2
APD의 최신 릴리스는 2004 (!)입니다. PHP 7에서는 작동하지 않습니다. PHP 5 용으로 설치하려고하면 pecl install apd"config.m4"에 대한 오류 메시지가 표시됩니다. 아직 시도하지 않은 소스에서 설치 해야하는 것 같습니다. 진심으로, Homebrew와 함께 설치되고 최소한의 설정이 필요하며 쉽게 읽을 수있는 출력을 제공하는 PHP 용 최신 CLI 기반 프로파일 링 도구가 없습니까?
forthrin

267

당신은 내가 생각하는 xdebug를 원한다 . 서버에 설치하고 전원을 켜고 kcachegrind (Linux의 경우) 또는 wincachegrind (Windows의 경우) 를 통해 출력을 펌핑 하면 정확한 타이밍, 카운트 및 메모리 사용량을 자세히 보여주는 몇 가지 예쁜 차트가 표시됩니다 (그러나 다른 확장 프로그램이 필요합니다).

그것은 심각하게 흔들린다 : D


6
APD 솔루션보다 구현하기가 훨씬 쉽다는 것을 알았습니다. 그러나 어쩌면 APD가 내 시스템에서 제대로 컴파일되지 않았기 때문일 수 있습니다. 또한 kcachegrind의 차트는 약속 한대로 아름답습니다.
wxs

1
@EvilPuppetMaster의 경우 --enable-memory-limit로 PHP를 컴파일하거나 최신 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 () = win
quano

3
XAMPP를 사용하여 Windows에서 작업하기가 매우 쉬웠습니다. 이미 xdebug에 대해 netbeans를 구성했습니다. php.ini의 xdebug 설정을 xdebug.profiler_output_name = "cachegrind.out. % t- % s"로 변경하지 않으면 출력이 생성되지 않습니다. 아파치를 다시 시작해야합니다.
beginner_

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_print ()가 끝에있는 prof_flag ()를 호출하는 예입니다.

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
DB에 연결
   0.003518
쿼리 수행
   0.000308
데이터 검색
   0.000009
닫기 DB
   0.000049
완료


37

오프라인으로 진행중인 SO Documentation 베타에서 내 참조를 교차 게시합니다.

XDebug로 프로파일 링

Xdebug라는 PHP 확장을 사용하여 PHP 디버깅 및 런타임 디버깅 을 지원할 수 있습니다 . 프로파일 러를 실행할 때 출력은 "cachegrind"라는 이진 형식으로 파일에 기록됩니다. 이러한 파일을 분석하기 위해 각 플랫폼에서 응용 프로그램을 사용할 수 있습니다. 이 프로파일 링을 수행하기 위해 애플리케이션 코드를 변경할 필요가 없습니다.

프로파일 링을 활성화하려면 확장 기능을 설치하고 php.ini 설정을 조정하십시오. 일부 Linux 배포판에는 표준 패키지 (예 : Ubuntu php-xdebug패키지)가 제공됩니다. 이 예에서는 요청 매개 변수를 기반으로 선택적으로 프로파일을 실행합니다. 이를 통해 설정을 정적으로 유지하고 필요한 경우에만 프로파일 러를 켤 수 있습니다.

# 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

기본적으로 파일 이름의 숫자는 파일 이름을 쓴 프로세스 ID입니다. 이것은 xdebug.profiler_output_name설정 으로 구성 할 수 있습니다.

실행되는 PHP 요청 / 프로세스마다 하나의 파일을 작성합니다. 예를 들어, 양식 게시물을 분석하려는 경우 HTML 양식을 표시하기 위해 GET 요청에 대해 하나의 프로파일이 작성됩니다. XDEBUG_PROFILE 매개 변수는 양식을 처리하는 두 번째 요청을 분석하기 위해 후속 POST 요청으로 전달되어야합니다. 따라서 프로파일 링 할 때 curl을 실행하여 양식을 직접 POST하는 것이 더 쉬운 경우가 있습니다.

출력 분석

작성된 후 KCachegrind 또는 Webgrind 와 같은 응용 프로그램에서 프로파일 캐시를 읽을 수 있습니다 . 널리 사용되는 PHP IDE 인 PHPStorm 도이 프로파일 링 데이터를 표시 할 수 있습니다 .

KCachegrind

예를 들어 KCachegrind는 다음과 같은 정보를 표시합니다.

  • 실행 된 기능
  • 자체 및 후속 함수 호출을 포함한 호출 시간
  • 각 함수가 호출 된 횟수
  • 통화 그래프
  • 소스 코드에 대한 링크

찾아야 할 것

분명히 성능 조정은 각 응용 프로그램의 사용 사례에 따라 매우 다릅니다. 일반적으로 다음을 찾는 것이 좋습니다.

  • 예상치 못한 동일한 함수를 반복해서 호출합니다. 데이터를 처리하고 쿼리하는 함수의 경우 응용 프로그램이 캐시 할 수있는 주요 기회가 될 수 있습니다.
  • 느리게 실행되는 기능. 응용 프로그램은 대부분의 시간을 어디에 소비합니까? 성능 조정에서 가장 좋은 결과는 가장 많은 시간을 소비하는 애플리케이션 부분에 초점을 맞추는 것입니다.

참고 : Xdebug, 특히 프로파일 링 기능은 리소스를 많이 사용하며 PHP 실행 속도를 늦 춥니 다. 프로덕션 서버 환경에서는이를 실행하지 않는 것이 좋습니다.


3
프로파일 캐시를 구문 분석을위한 도구 목록에 추가 : PhpStorm 또한 프로필 캐시 미리 볼 수있는 도구를 가지고
peterchaula

1
@ peter PHPStorm이 그 기능을 가지고 있다는 것을 잊었습니다. 설명서에 대한 링크와 함께 추가했습니다. 감사!
Matt S

서버에서 직접 텍스트 (GUI가 아닌) 보고서를 얻는 방법은 무엇입니까?
Alexander Shcheblikin

1
@Mark는 이것을 답변으로 표시 할 수 있습니까? 현재 답변은 게시 되어도 수년 동안 작동하지 않았지만 오래되었습니다. 이것은 효과가 있으며 더 좋은 방법은 없습니다.
Mawg는 모니카

24

마이크로 타임을 빼면 부정적인 결과가 나오면 인수 true( microtime(true)) 와 함께 함수를 사용해보십시오 . 을 사용 true하면 함수가 문자열 대신 부동 소수점을 반환합니다 (인수없이 호출 된 것처럼).


24

솔직히, 프로파일 링을 위해 NewRelic을 사용하는 것이 가장 좋습니다.

그것은 런타임을 전혀 늦추지 않는 PHP 확장이며 적절한 모니터링을 허용합니다. 비싼 버전에서는 무거운 드릴 다운을 허용하지만 가격 모델을 감당할 수는 없습니다.

그럼에도 불구하고, 무료 / 표준 계획이 있더라도, 매달린 과일의 대부분이 어디에 있는지 분명하고 간단합니다. 또한 DB 인터랙션에 대한 아이디어를 제공 할 수도 있습니다.

프로파일 링시 인터페이스 중 하나의 스크린 샷


16
새로운 유물은 유망 해 보입니다. 그러나 개인 정보 보호 정책 의 "응용 프로그램 데이터 공개"부분이 즉시 철회되었습니다. Imho, 독점 소스 코드 조각을 타사와 공유 하는 것은 약간 너무 큽니다.
Cengiz Can 11

8
여기서 방어력을 뛰어 넘지는 않지만 "응용 프로그램 데이터"는 응용 프로그램 소스 코드가 아닌 성능 정보 및 시스템 구성 정보입니다.
David Shields

내 새 유물이 내 "WebTransaction"을 99 %로 표시하고 있으며 "ApplicationTraces"에 대한 프로 계정이 없습니다
Karthik T

1
newrelic.com/rackspace 에서 가입을 시도 하십시오 <무료로 "표준"을 제공해야합니다
zeroasterisk

15

불쌍한 남자의 프로파일 링, 확장이 필요하지 않습니다. 중첩 된 프로파일 및 총 백분율을 지원합니다.

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 년 마지막 업데이트 5.3, 5.4 이후 ...에 대한 PEAR 패키지 없다
dland

1
Facebook은 PHP 5.5를 통해 지원되는 포크를 만들었습니다. github.com/facebook/xhprof
borkencode

추가 조정을 제안하는이 포크를 확인하십시오 : github.com/preinheimer/xhprof
Fedir RYKHTIK

xhprof.io 는 XHProf를 사용하여 수집 된 데이터에 대한 GUI를 제공하고 기록 분석 목적으로 데이터베이스에 데이터를 저장할 수 있습니다. 나는 후자의 구현의 저자입니다.
Gajus

10

프로파일 링에 phpDebug를 사용하고 싶습니다. http://phpdebug.sourceforge.net/www/index.html

포함 된 모든 파일뿐만 아니라 사용 된 모든 SQL에 대한 모든 시간 / 메모리 사용량을 출력합니다. 분명히 추상화 된 코드에서 가장 잘 작동합니다.

함수 및 클래스 프로파일 링에는 microtime()+ get_memory_usage()+ 만 사용 get_peak_memory_usage()합니다.



6

귀하의 예와 같이 벤치마킹을 위해 pear Benchmark 패키지를 사용합니다 . 측정 마커를 설정합니다. 이 클래스는 또한 몇 가지 프레젠테이션 도우미를 제공하거나 데이터를 적절하게 처리 할 수 ​​있습니다.

실제로 __destruct 메서드를 사용하여 다른 클래스에 래핑했습니다. 스크립트가 종료되면 log4php를 통해 출력이 syslog에 기록되므로 작업 할 성능 데이터가 많이 있습니다.


3

XDebug는 안정적이지 않으며 특정 PHP 버전에서 항상 사용 가능한 것은 아닙니다. 예를 들어 일부 서버에서는 여전히 php-5.1.6을 실행합니다 .RedHat RHEL5와 함께 제공되며 btw는 여전히 모든 중요한 문제에 대한 업데이트를 수신하며 최근 XDebug는이 PHP로 컴파일되지 않습니다. 나는로 전환하여 결국 그래서 디버거 DBG 그것의 PHP를 벤치마킹 기능, 방법, 모듈과 짝수 라인에 대한 타이밍을 제공합니다.


2

이 새로운 PHP 프로파일 러를 반드시 확인해야합니다.

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

PHP 프로파일 러가 결과를 수집하고 제시하는 방법을 재정의합니다. PHP-SPX는 총 특정 함수 호출과 실행에 소요 된 총 시간을 출력하는 대신 요청 실행의 전체 타임 라인을 완벽하게 읽을 수있는 방식으로 제시합니다. 아래는 GUI가 제공하는 화면입니다.

여기에 이미지 설명을 입력하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.