문제

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

나는 모든 함수 호출의 덤프와 소요 시간을 보여주는 무언가를 추가하고 싶지만 특정 함수에 대해 무언가를 배치하는 것도 괜찮습니다.

나는 실험을 시도했다. 마이크로타임 기능:

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

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

하지만 그것은 때때로 나에게 부정적인 결과를 안겨줍니다.게다가 내 코드 전체에 이를 뿌리는 것도 많은 문제입니다.

도움이 되었습니까?

해결책

그만큼 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년에 출시되었으며 확장 버전은 더 이상 유지되지 않습니다 다양한 호환성 문제가 있습니다(설명 참조).

다른 팁

당신이 원하는 xdebug 제 생각에는.서버에 설치하고 전원을 켜고 출력을 펌핑합니다. kcachegrind (리눅스의 경우) 또는 윈캐시그라인드 (Windows의 경우) 정확한 타이밍, 개수 및 메모리 사용량을 자세히 설명하는 몇 가지 멋진 차트가 표시됩니다(그러나 이를 위해서는 또 다른 확장이 필요합니다).

심각하게 흔들립니다 :D

확장이 필요하지 않습니다. 간단한 프로파일링을 위해 이 두 기능을 사용하면 됩니다.

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

오프라인으로 전환되는 SO Documentation 베타에서 내 참조를 교차 게시합니다.

XDebug를 사용한 프로파일링

Xdebug라는 PHP 확장 기능을 사용하여 다음 작업을 수행할 수 있습니다. PHP 애플리케이션 프로파일링, 런타임 디버깅도 가능합니다.프로파일러를 실행할 때 출력은 "cachegrind"라는 바이너리 형식의 파일에 기록됩니다.이러한 파일을 분석하기 위해 각 플랫폼에서 애플리케이션을 사용할 수 있습니다. 이 프로파일링을 수행하기 위해 애플리케이션 코드를 변경할 필요는 없습니다.

프로파일링을 활성화하려면 확장 기능을 설치하고 php.ini 설정을 조정하세요.일부 Linux 배포판에는 표준 패키지가 함께 제공됩니다(예:우분투의 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 요청에 전달해야 합니다.따라서 프로파일링할 때 컬을 실행하여 양식을 직접 POST하는 것이 더 쉬운 경우가 있습니다.

출력 분석

일단 작성된 프로필 캐시는 다음과 같은 응용 프로그램에서 읽을 수 있습니다. KCachegrind 또는 웹그라인드.인기 있는 PHP IDE인 PHPStorm도 가능합니다. 이 프로파일링 데이터를 표시합니다.

KCachegrind

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

  • 실행된 기능
  • 호출 시간(자체 및 후속 함수 호출 포함)
  • 각 함수가 호출된 횟수
  • 호출 그래프
  • 소스 코드 링크

무엇을 찾아야 할까요?

분명히 성능 조정은 각 애플리케이션의 사용 사례에 따라 매우 구체적입니다.일반적으로 다음을 찾는 것이 좋습니다.

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

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

마이크로타임을 빼면 부정적인 결과가 나오면 인수와 함께 함수를 사용해 보세요. true (microtime(true)).와 함께 true, 함수는 문자열 대신 부동 소수점을 반환합니다(인수 없이 호출되는 경우와 마찬가지로).

솔직히 NewRelic을 프로파일링에 사용하는 것이 가장 좋다고 주장하겠습니다.

런타임 속도를 전혀 저하시키지 않는 PHP 확장이며 모니터링을 수행하므로 적절한 드릴다운이 가능합니다.값비싼 버전에서는 철저한 드릴다운이 가능합니다(그러나 가격 책정 모델을 감당할 수는 없습니다).

그럼에도 불구하고 무료/표준 계획을 사용하더라도 대부분의 낮은 매달린 과일이 어디에 있는지는 분명하고 간단합니다.또한 DB 상호 작용에 대한 아이디어도 제공할 수 있다는 점이 마음에 듭니다.

screenshot of one of the interfaces when profiling

PECL XHPROF 재미있어 보여요.그것은 가지고있다 클릭 가능한 HTML 인터페이스 보고서를 보는 데 매우 간단합니다. 선적 서류 비치.그래도 아직 테스트하지는 않았습니다.

불쌍한 사람의 프로파일링, 확장이 필요하지 않습니다.중첩된 프로필 및 전체 비율을 지원합니다.

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

나는 프로파일링을 위해 phpDebug를 사용하는 것을 좋아합니다.http://phpdebug.sourceforge.net/www/index.html

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

함수 및 클래스 프로파일링에는 다음을 사용하겠습니다. microtime() + get_memory_usage() + get_peak_memory_usage().

나는 도전적으로 줄 것이다 검은 화재 시도.

내가 사용하여 만든 virtualBox가 있습니다. 꼭두각시, BlackFire와 함께 제공되는 다양한 PHP 프레임워크를 테스트하려면 필요한 경우 자유롭게 포크 및/또는 배포하시기 바랍니다 :)

https://github.com/webit4me/PHPFrameworks

귀하의 예와 같이 벤치마킹을 위해 저는 배 벤치마크 패키지.측정을 위해 마커를 설정합니다.또한 수업에서는 몇 가지 프레젠테이션 도우미를 제공하거나 적절하다고 판단되는 대로 데이터를 처리할 수 있습니다.

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

XDebug는 안정적이지 않으며 특정 PHP 버전에서 항상 사용할 수 있는 것은 아닙니다.예를 들어 일부 서버에서는 여전히 php-5.1.6을 실행합니다. 이는 RedHat RHEL5와 함께 제공되는 것이며(btw는 여전히 모든 중요한 문제에 대한 업데이트를 받습니다), 최근 XDebug는 이 PHP로 컴파일조차 하지 않습니다.그래서 결국 전환하게 됐어요 DBG 디버거그것은 PHP 벤치마킹 함수, 메소드, 모듈 및 라인에 대한 타이밍을 제공합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top