2016-11-16 54 views
1

Tutfe是一個剖析庫,它非常適合理解運行時的組成,特別是在複雜的調用棧中。如何用Tufte剖析多線程clojure結果

當我在我的項目中運行它時,我預期代碼段的性能價格昂貴,並未在結果中註冊爲高級用戶,這導致發現Tufte(合理)僅捕獲了線程本地結果。

的文檔表明,它有內置的結合上使用{:dynamic? true}選擇其他線程儀器累計時間,但似乎更需要爲了捕捉積累的其它線程,如由pmap啓動時間

這裏是原來的塔夫特的演示,一些多線程介紹:

(require '[taoensso.tufte :as tufte :refer (defnp p profiled profile)]) 

;; We'll request to send `profile` stats to `println`: 
(tufte/add-basic-println-handler! {}) 

;;; Let's define a couple dummy fns to simulate doing some expensive work 
(defn get-x [] (Thread/sleep 500)    "x val") 
(defn get-y [] 
    (pmap 
    #(do 
     (Thread/sleep 500) 
     (print %)) 
    (range 10))) 

;; How do these fns perform? Let's check: 

(profile ; Profile any `p` forms called during body execution 
    {:dynamic? true} ; Profiling options; we'll use the defaults for now 
    (dotimes [_ 5] 
    (p :get-x (get-x)) 
    (p :get-y (get-y)))) 

輸出表明println語句強行線程來評估。然而,get-y累計時間並未顯示在結果中:

2187306594=> nil 
=> #{:basic-println} 
=> #'user/get-x 
=> #'user/get-y 
8904365271703695842110783956243415760829=> nil 

     pId  nCalls  Min  Max  MAD  Mean Time% Time 
    :get-x   5 500.52ms 504.84ms 1.44ms 502.44ms  100 2.51s 
    :get-y   5 90.67μs 581.91μs 162.2μs 269.29μs  0 1.35ms 
Clock Time               100 2.51s 
Accounted Time              100 2.51s 

回答

3

答案:延遲初始化。雖然數據正在被打印到屏幕上,但這是(profile...)表格的結尾,它是在偵察表格get-y之外進行的。

這將產生同樣的效果:雖然這一次實現了get-Y剖面裏面的懶惰序列

(profile ; Profile any `p` forms called during body execution 
    {:dynamic? true} ; Profiling options; we'll use the defaults for now 
    (dotimes [_ 5] 
    (p :get-x (get-x)) 
    (doall (p :get-y (get-y))))) 

30167894521045768392530798241651268940371023657894=> nil 

      pId  nCalls  Min  Max  MAD  Mean Time% Time 
     :get-x   5 500.07ms 504.58ms 1.41ms 503.08ms  50 2.52s 
     :get-y   5 80.25μs 126.18μs 15.98μs 104.84μs  0 524.18μs 
    Clock Time               100 5.03s 
Accounted Time               50 2.52s 

(profile ; Profile any `p` forms called during body execution 
    {:dynamic? true} ; Profiling options; we'll use the defaults for now 
    (dotimes [_ 5] 
    (p :get-x (get-x)) 
    (p :get-y (doall (get-y))))) 

12037645987105892436354169872031089546721058729634=> nil 

      pId  nCalls  Min  Max  MAD  Mean Time% Time 
     :get-x   5 502.54ms 504.71ms 705.6μs 503.5ms  50 2.52s 
     :get-y   5 501.69ms 505.68ms 1.05ms 503.06ms  50 2.52s 
    Clock Time               100 5.03s 
Accounted Time               100 5.03s 

這是重要的是知道的分析經驗,因爲當處理懶惰序列時,您正在實現它們如何使用的性能,而不是序列本身:

(profile ; Profile any `p` forms called during body execution 
    {:dynamic? true} ; Profiling options; we'll use the defaults for now 
    (dotimes [_ 5] 
    (p :get-x (get-x)) 
    (p ::realize-y 
     (doall (p :get-y (get-y)))))) 

06538947123410695278450678913223071958645126380479=> nil 

      pId  nCalls  Min  Max  MAD  Mean Time% Time 
:user/realize-y   5 503.29ms 504.86ms 458.12μs 504.37ms  50 2.52s 
     :get-x   5 500.13ms 505.06ms  1.4ms 503.64ms  50 2.52s 
     :get-y   5 86.0μs  1.15ms 331.81μs 322.94μs  0 1.61ms 
    Clock Time               100 5.04s 
Accounted Time               100 5.04s