R Language
कोड प्रोफाइलिंग
खोज…
सिस्टम का समय
सिस्टम समय आपको एक आर एक्सप्रेशन निष्पादित करने के लिए आवश्यक सीपीयू समय देता है, उदाहरण के लिए:
system.time(print("hello world"))
# [1] "hello world"
# user system elapsed
# 0 0 0
आप ब्रेसिज़ के उपयोग के माध्यम से कोड के बड़े टुकड़े जोड़ सकते हैं:
system.time({
library(numbers)
Primes(1,10^5)
})
या कार्यों का परीक्षण करने के लिए इसका उपयोग करें:
fibb <- function (n) {
if (n < 3) {
return(c(0,1)[n])
} else {
return(fibb(n - 2) + fibb(n -1))
}
}
system.time(fibb(30))
proc.time ()
इसकी सरलतम पर, proc.time()
वर्तमान प्रक्रिया के लिए सेकंड में कुल बीता हुआ CPU समय देता है। कंसोल में इसे निष्पादित करने से निम्न प्रकार का आउटपुट प्राप्त होता है:
proc.time()
# user system elapsed
# 284.507 120.397 515029.305
यह कोड की विशिष्ट लाइनों को बेंचमार्क करने के लिए विशेष रूप से उपयोगी है। उदाहरण के लिए:
t1 <- proc.time()
fibb <- function (n) {
if (n < 3) {
return(c(0,1)[n])
} else {
return(fibb(n - 2) + fibb(n -1))
}
}
print("Time one")
print(proc.time() - t1)
t2 <- proc.time()
fibb(30)
print("Time two")
print(proc.time() - t2)
यह निम्न आउटपुट देता है:
source('~/.active-rstudio-document')
# [1] "Time one"
# user system elapsed
# 0 0 0
# [1] "Time two"
# user system elapsed
# 1.534 0.012 1.572
system.time()
proc.time()
लिए एक आवरण है जो किसी विशेष कमांड / अभिव्यक्ति के लिए बीता हुआ समय लौटाता है।
print(t1 <- system.time(replicate(1000,12^2)))
## user system elapsed
## 0.000 0.000 0.002
ध्यान दें कि लौटी हुई वस्तु, वर्ग proc.time
, सतह पर दिखाई देने वाली की तुलना में थोड़ी अधिक जटिल है:
str(t1)
## Class 'proc_time' Named num [1:5] 0 0 0.002 0 0
## ..- attr(*, "names")= chr [1:5] "user.self" "sys.self" "elapsed" "user.child" ...
रेखा प्रोफाइलिंग
लाइन प्रोफाइलिंग के लिए एक पैकेज लाइनफ़ॉर्म है जो हैडली विकम द्वारा लिखा और बनाए रखा गया है। यह पूर्वानुमान पैकेज में auto.arima
साथ काम करने का एक त्वरित प्रदर्शन है:
library(lineprof)
library(forecast)
l <- lineprof(auto.arima(AirPassengers))
shine(l)
यह आपको एक चमकदार ऐप प्रदान करेगा, जो आपको हर फ़ंक्शन कॉल में गहराई से डील करने की अनुमति देता है। इससे आप आसानी से देख सकते हैं कि आपका R कोड धीमा हो रहा है। नीचे चमकदार ऐप का एक स्क्रीनशॉट है:
Microbenchmark
माइक्रोबेनमार्क, अन्यथा तेज प्रक्रियाओं के लिए समय लेने का अनुमान लगाने के लिए उपयोगी है। उदाहरण के लिए, हैलो दुनिया को मुद्रित करने में लगने वाले समय का अनुमान लगाने पर विचार करें।
system.time(print("hello world"))
# [1] "hello world"
# user system elapsed
# 0 0 0
इसका कारण यह है कि system.time
अनिवार्य रूप से proc.time
लिए एक आवरण फ़ंक्शन है, जो सेकंड में मापता है। जैसा कि "हैलो वर्ल्ड" को प्रिंट करने में एक सेकंड से भी कम समय लगता है, ऐसा प्रतीत होता है कि लिया गया समय एक सेकंड से भी कम है, हालांकि यह सच नहीं है। यह देखने के लिए हम पैकेज माइक्रोबेनमार्क का उपयोग कर सकते हैं:
library(microbenchmark)
microbenchmark(print("hello world"))
# Unit: microseconds
# expr min lq mean median uq max neval
# print("hello world") 26.336 29.984 44.11637 44.6835 45.415 158.824 100
यहां हम रनिंग print("hello world")
100 बार देख सकते हैं, औसतन लिया गया समय वास्तव में 44 माइक्रोसेकंड था। (ध्यान दें कि इस कोड को चलाने पर कंसोल पर "हैलो वर्ल्ड" 100 बार प्रिंट होगा।)
हम इसकी तुलना एक समकक्ष प्रक्रिया, cat("hello world\n")
, यह देखने के लिए कि क्या यह print("hello world")
से तेज है:
microbenchmark(cat("hello world\n"))
# Unit: microseconds
# expr min lq mean median uq max neval
# cat("hello world\\n") 14.093 17.6975 23.73829 19.319 20.996 119.382 100
इस मामले में cat()
print()
तुलना में लगभग दोगुनी है print()
।
वैकल्पिक रूप से एक ही microbenchmark
कॉल के भीतर दो प्रक्रियाओं की तुलना कर सकते हैं:
microbenchmark(print("hello world"), cat("hello world\n"))
# Unit: microseconds
# expr min lq mean median uq max neval
# print("hello world") 29.122 31.654 39.64255 34.5275 38.852 192.779 100
# cat("hello world\\n") 9.381 12.356 13.83820 12.9930 13.715 52.564 100
बेंचमार्किंग का उपयोग करते हुए माइक्रोबेनमार्क
आप "अभिव्यक्ति मूल्यांकन के सटीक-मिलीसेकंड सटीक समय" का संचालन करने के लिए microbenchmark
पैकेज का उपयोग कर सकते हैं।
इस उदाहरण में हम एक समूह में तत्वों को अद्यतन करने के लिए छह समकक्ष data.table
की गति की तुलना कर रहे हैं। एक निश्चित स्थिति के आधार पर।
अधिक विशेष रूप से:
3 कॉलम के साथ एक
data.table
:id
,time
औरstatus
। प्रत्येक आईडी के लिए, मैं अधिकतम समय के साथ रिकॉर्ड ढूंढना चाहता हूं - फिर यदि उस रिकॉर्ड के लिए यदि स्थिति सत्य है, तो मैं इसे झूठा सेट करना चाहता हूं यदि समय> 7 है
library(microbenchmark)
library(data.table)
set.seed(20160723)
dt <- data.table(id = c(rep(seq(1:10000), each = 10)),
time = c(rep(seq(1:10000), 10)),
status = c(sample(c(TRUE, FALSE), 10000*10, replace = TRUE)))
setkey(dt, id, time) ## create copies of the data so the 'updates-by-reference' don't affect other expressions
dt1 <- copy(dt)
dt2 <- copy(dt)
dt3 <- copy(dt)
dt4 <- copy(dt)
dt5 <- copy(dt)
dt6 <- copy(dt)
microbenchmark(
expression_1 = {
dt1[ dt1[order(time), .I[.N], by = id]$V1, status := status * time < 7 ]
},
expression_2 = {
dt2[,status := c(.SD[-.N, status], .SD[.N, status * time > 7]), by = id]
},
expression_3 = {
dt3[dt3[,.N, by = id][,cumsum(N)], status := status * time > 7]
},
expression_4 = {
y <- dt4[,.SD[.N],by=id]
dt4[y, status := status & time > 7]
},
expression_5 = {
y <- dt5[, .SD[.N, .(time, status)], by = id][time > 7 & status]
dt5[y, status := FALSE]
},
expression_6 = {
dt6[ dt6[, .I == .I[which.max(time)], by = id]$V1 & time > 7, status := FALSE]
},
times = 10L ## specify the number of times each expression is evaluated
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# expression_1 11.646149 13.201670 16.808399 15.643384 18.78640 26.321346 10
# expression_2 8051.898126 8777.016935 9238.323459 8979.553856 9281.93377 12610.869058 10
# expression_3 3.208773 3.385841 4.207903 4.089515 4.70146 5.654702 10
# expression_4 15.758441 16.247833 20.677038 19.028982 21.04170 36.373153 10
# expression_5 7552.970295 8051.080753 8702.064620 8861.608629 9308.62842 9722.234921 10
# expression_6 18.403105 18.812785 22.427984 21.966764 24.66930 28.607064 10
आउटपुट से पता चलता है कि इस परीक्षण में expression_3
सबसे तेज है।
संदर्भ
data.table - कॉलम जोड़ना और संशोधित करना
data.table - data.table में विशेष ग्रुपिंग सिंबल