2010-04-25 49 views
3

我很想重新提出這個問題'看看這塊磚頭。它屬於哪種類型的房子?'如何在不使用模塊的情況下剖析子程序?

情況如下:我實際上已被要求剖析一些既不能訪問性能分析器(即使Devel::DProf)也不使用Time::HiRes的子程序。這個練習的目的是'找到'瓶頸。

目前,我在每個子記錄的開頭和結尾處噴印打印語句,以便記錄條目並退出到文件,以及time函數的結果。不理想,但是這是我能夠在情況下最好的。至少它會讓我看到每個子被調用的次數。

該代碼在Unix下運行。我看到的最接近的東西是perlfaq8,但這似乎沒有幫助(我不知道如何製作syscall,並且想知道它會不可預測地影響代碼時序)。

不是典型的日常SO問題...

+0

@FM:好主意,但我需要考慮一下。據我所知,它們將運行良好的一千倍(代碼亂七八糟)。麻煩的是,這些潛艇 - 其中有許多是相互關聯的。 – Zaid 2010-04-25 16:18:20

+3

那麼,你做模塊做同樣的事情。看看他們的來源。 – 2010-04-25 22:16:49

+0

您無權訪問Time :: HiRes?你使用Perl 5.6嗎?之後,它就是隨Perl安裝的模塊的一部分。 – MkV 2010-05-04 05:49:44

回答

7

This technique should work.

基本上,這個想法是,如果你與-d標誌運行Perl,它進入調試器。然後,當你運行這個程序時,ctrl-Break或者ctrl-C會導致它在它正在做的事情中間暫停。然後,您可以鍵入T以顯示堆棧,並在繼續之前檢查其他任何變量(如果您喜歡)。

做大約10次或20次。任何花費大量時間的代碼行(或任何函數,如果您願意的話)都會出現在堆棧樣本的百分比上,大概是這樣,所以您不會錯過它。例如,如果一行代碼(通常是函數調用)花費20%的時間,並且您暫停程序20次,那麼您將在4個堆棧樣本上看到該行,給出或取1.8個樣本。如果您可以避免執行該行,或者執行時間較少,那麼可以節省的時間就是整個執行時間縮短20%。

然後你可以重複它來發現更多的問題。

你說的目的是'找到'瓶頸。這個方法就是這樣。度量函數執行時間只是一個非常間接的方法。

+0

@Zaid:以防萬一你試圖迴應評論說這是太多的工作,試試看。你可能會驚訝於它是多麼容易和有效。 – 2010-04-25 16:11:45

+0

@Mike:點好了,但我的上司想要時間。關於瓶頸和過多停留時間在哪裏,我有一個很好的直覺,但我需要量化它。 – Zaid 2010-04-25 16:19:57

+0

@Zaid:爲了獲得時間,請花費總體執行時間(秒錶)並乘以百分比。如果他們想*精確*時間,他們就錯過了這一點。如果問題出現的時候你有一個相當好的直覺,那麼抽樣可能證明你是對的,或者告訴你問題的真相在哪裏。 – 2010-04-25 16:34:02

1
  1. 至於syscall,有一個在這個職位一個很好的例子:http://www.cpan.org/scripts/date_and_time/gettimeofday

    我認爲它甚至有人之前誰從未使用過的系統調用足夠清晰(像我一樣:)

  2. 五月我問什麼「無法訪問」的具體內容是?

    通常可以訪問CPAN模塊,即使在中央位置不安裝它們的情況下也是如此。下載模塊有問題嗎?將它安裝在你的主目錄中?在模塊中使用軟件包括?

    如果其中一個是掛斷,它可能會被修復...如果是一些公司的政策,這是無價:(

+0

@DVK:長話短說:這不是爲了個人使用。 NDA – Zaid 2010-04-25 18:30:53

+0

@Zaid - 你不能與The Man戰鬥:( – DVK 2010-04-25 18:40:40

+0

@Zaid - 我添加了一個使用系統調用的例子 - 看看你是否可以重新使用... – DVK 2010-04-25 18:46:06

0

好了,你可以編寫自己的概要。因爲它聽起來這不是那麼糟糕。一個探查僅僅是一個非常特殊的情況下調試器。你想讀一些好的第一切割代碼perldebguts手冊頁,如果你必須編寫自己上手。

,和你的老闆想要什麼,儘管他或她可能不知道,是用什麼Devel::NYTProf可以很好地分析代碼,並完成工作,而不必等待您部分複製函數在瞭解它是如何完成的。

您提出的關於「個人使用」的評論沒有意義。你正在爲工作做好工作,而工作需要完成,並且你需要(或者你的經理需要得到你)資源來完成這項工作。 「個人使用」似乎沒有進入它。

是否有人拒絕在模塊上簽名以使其安裝在運行待測軟件的機器上?這是一個授權問題嗎?是不是被允許在生產機器上安裝任意軟件(可以理解,但軟件在上線之前必須經過測試 - 我希望 - 可以在那裏測試)?

從可信來源的知名模塊不能使用的原因是什麼?你是否已經向你的經理提出了這樣一個案例:從頭開始編寫一個新的,功能較少的分析器花費的錢比找到一種既好又可用的方法花費更多的錢?

+0

我完全同意'Devel :: NYTProf'會我希望我可以多說一些,但是我的手(和舌頭)綁在一起,無論如何,謝謝 – Zaid 2010-05-04 05:45:45

0

對於每個子程序,圍繞它創建一個包裝,以某種格式報告時間,您可以將其導出爲R,數據庫,Excel或類似的東西(CSV將是一個不錯的選擇)。向你的代碼中添加這樣的內容。如果您使用的是小於5.7的Perl(當Time :: HiRes首次添加到內核時),請使用上面提到的syscall而不是下面的Time :: HiRes的函數。

INIT { 
    sub wrap_sub { 
     no strict 'refs'; 
     my $sub = shift; 
     my $subref = *{$sub}{CODE}; 
     return sub { 
      local *__ANON__ = "wrapped_$sub"; 
      my $fsecs = Time::HiRes::gettimeofday(); 
      print STDERR "$sub,$fsecs,"; 
      if (wantarray) { 
       @return = eval { $subref->(@_) } or die [email protected]; 
      } else { 
       $return[0] = eval { $subref->(@_) } or die [email protected]; 
      } 

      $fsecs = Time::HiRes::gettimeofday(); 
      print STDERR "$fsecs\n"; 
      return wantarray ? @return : $return[0]; 
     }; 
    } 
    require Time::HiRes; 
    my @subs = qw{the subs you want to profile}; 
    no strict 'refs'; 
    no warnings 'redefine'; 
    foreach my $sub (@subs) { 
     *{$sub} = wrap_sub($sub); 
    }  
} 

用您需要異形潛艇「要分析潛艇」,並使用開放式()的文件處理,而不是STDERR,如果你需要,牢記你可以得到運行結果獨立於腳本的輸出(在Unix上,使用Bourne,Korn和bash shell),像這樣:

perl ./myscript.pl 2>myscript.profile 
+0

當我使用上面的代碼,並在那裏輸入2個子程序的名字時,我得到了'1380617457.79998'。這是否意味着?我無法從上述結果中提取2個子程序所用的時間。 – 2013-10-01 08:55:02

相關問題