2012-12-01 164 views
5

我必須對大數據集(主要使用data.table,RStudio)進行大量數據操作。我想監視每個步驟的運行時間,而無需在每個步驟中顯式調用system.time()。默認情況下返回system.time

在每個步驟默認情況下是否有包或簡單的方式顯示運行時間?

謝謝。

+1

你可以看到這個http://stackoverflow.com/questions/8439957/multi-function-tester-alternative-to-system-time – agstudy

+0

感謝agstudy 。我知道rbenchmark,但這不是我所需要的。我想有一個「副作用」,它會爲每個R函數調用產生運行時間。我不確定這是否可能,儘管 – AdamNYC

+0

這很棒問題,甚至更多,因爲我發現即使你在大項目的每一步中使用'system.time',並且有很多'source'調用和函數,'system.time'在源文件和內部函數中請求被忽略了(也許有一種方法可以解決這個問題,就像'print'一樣,但我還沒有證實,這是我的前問題的一部分研究這個確切主題的潛在問題)。 –

回答

5

這不完全是你要求的,但我寫了time_file(https://gist.github.com/4183595)其中source()是一個R文件,並運行代碼,然後重寫該文件,插入包含每個頂級語句花費多長時間運行的註釋。

time_file()變成這樣:

{ 
    load_all("~/documents/plyr/plyr") 
    load_all("~/documents/plyr/dplyr") 
    library(data.table) 
    data("baseball", package = "plyr") 
    vars <- list(n = quote(length(id)), m = quote(n + 1)) 
} 

# Baseline case: use ddply 
a <- ddply(baseball, "id", summarise, n = length(id)) 

# New summary method: ~20x faster 
b <- summarise_by(baseball, group("id"), vars) 

# But still not as fast as specialised count, which is basically id + tabulate 
# so maybe able to eke out a little more with a C loop ? 
count(baseball, "id") 

到這一點:

{ 
    load_all("~/documents/plyr/plyr") 
    load_all("~/documents/plyr/dplyr") 
    library(data.table) 
    data("baseball", package = "plyr") 
    vars <- list(n = quote(length(id)), m = quote(n + 1)) 
} 

# Baseline case: use ddply 
a <- ddply(baseball, "id", summarise, n = length(id)) 
#: user system elapsed 
#: 0.451 0.003 0.453 

# New summary method: ~20x faster 
b <- summarise_by(baseball, group("id"), vars) 
#: user system elapsed 
#: 0.029 0.000 0.029 

# But still not as fast as specialised count, which is basically id + tabulate 
# so maybe able to eke out a little more with a C loop ? 
count(baseball, "id") 
#: user system elapsed 
#: 0.008 0.000 0.008 

它的頂級{塊內部沒有時間碼,這樣你就可以選擇不時間的東西,你」

我不認爲有沒有辦法自動添加計時作爲頂級效果而不會以某種方式修改您運行代碼的方式 - 即使用諸如time_file而不是source之類的東西。

您可能想知道每個頂級操作對代碼總體速度的影響。嗯,這很容易與微基準回答;)

library(microbenchmark) 
microbenchmark(
    runif(1e4), 
    system.time(runif(1e4)), 
    system.time(runif(1e4), gc = FALSE) 
) 

所以時間增加相對小的開銷(20μs的我的電腦上),但默認GC增加了每次通話約27毫秒。因此,除非您有數千個頂級通話,否則您不會看到太大的影響。

+0

我想知道是否用_every_函數調用檢查時間會減慢整個爬行的速度。 –

+0

@DWin微基準加入 - 每頂層函數調用大約需要20毫秒,這對大多數腳本不太可能有明顯的影響。 – hadley

+0

@Hadley does R有等價的python裝飾器?我問這個,因爲使用這個功能可以提高你的時間分析的清晰度。 – agstudy

0

我有充分的信貸,爲這些額外的答案Freenode#R IRC頻道的@jbecker,但對我的解決方案是在這裏:http://adv-r.had.co.nz/Profiling.html

下面是它只是一個小的味道:

「爲了理解性能,您使用了一個profiler,有許多不同類型的profiler,R使用一種相當簡單的類型,稱爲採樣或統計分析器,採樣profiler每隔幾毫秒就停止執行一次代碼,函數正在執行(沿着用哪個函數調用該函數,等等)。例如,考慮F(),如下:」

library(lineprof) 
f <- function() { 
    pause(0.1) 
    g() 
    h() 
} 
g <- function() { 
    pause(0.1) 
    h() 
} 
h <- function() { 
    pause(0.1) 
}