कभी-कभी हमें लूप्स का उपयोग करना पड़ता है, उदाहरण के लिए, जब हमें पता नहीं होता है कि परिणाम प्राप्त करने के लिए हमें कितने पुनरावृत्तियों की आवश्यकता है। उदाहरण के रूप में छोरों को लें। नीचे ऐसे तरीके दिए गए हैं जिनसे आपको बिल्कुल बचना चाहिए:
a=numeric(0)
b=1
system.time(
{
while(b<=1e5){
b=b+1
a<-c(a,pi)
}
}
)
# user system elapsed
# 13.2 0.0 13.2
a=numeric(0)
b=1
system.time(
{
while(b<=1e5){
b=b+1
a<-append(a,pi)
}
}
)
# user system elapsed
# 11.06 5.72 16.84
ये बहुत ही अयोग्य हैं क्योंकि आर हर बार जब यह वेक्टर को कॉपी करता है।
इंडेक्स का उपयोग करने के लिए सबसे प्रभावी तरीका है। ध्यान दें कि इस बार मैंने इसे 1e7 बार करने दिया, लेकिन यह अभी भी बहुत तेजी से है c
।
a=numeric(0)
system.time(
{
while(length(a)<1e7){
a[length(a)+1]=pi
}
}
)
# user system elapsed
# 5.71 0.39 6.12
यह स्वीकार्य है। और हम इसे बदल कर एक सा तेजी से कर सकते हैं [
के साथ [[
।
a=numeric(0)
system.time(
{
while(length(a)<1e7){
a[[length(a)+1]]=pi
}
}
)
# user system elapsed
# 5.29 0.38 5.69
हो सकता है कि आपने पहले से ही ध्यान दिया length
हो जो समय लेने वाला हो। यदि हम length
एक काउंटर से प्रतिस्थापित करते हैं:
a=numeric(0)
b=1
system.time(
{
while(b<=1e7){
a[[b]]=pi
b=b+1
}
}
)
# user system elapsed
# 3.35 0.41 3.76
जैसा कि अन्य उपयोगकर्ताओं ने उल्लेख किया है, वेक्टर को पूर्व-आवंटित करना बहुत मददगार है। लेकिन यह गति और स्मृति उपयोग के बीच एक व्यापार-बंद है यदि आप नहीं जानते कि परिणाम प्राप्त करने के लिए आपको कितने लूप की आवश्यकता है।
a=rep(NaN,2*1e7)
b=1
system.time(
{
while(b<=1e7){
a[[b]]=pi
b=b+1
}
a=a[!is.na(a)]
}
)
# user system elapsed
# 1.57 0.06 1.63
एक मध्यवर्ती विधि धीरे-धीरे परिणामों के ब्लॉक को जोड़ना है।
a=numeric(0)
b=0
step_count=0
step=1e6
system.time(
{
repeat{
a_step=rep(NaN,step)
for(i in seq_len(step)){
b=b+1
a_step[[i]]=pi
if(b>=1e7){
a_step=a_step[1:i]
break
}
}
a[(step_count*step+1):b]=a_step
if(b>=1e7) break
step_count=step_count+1
}
}
)
#user system elapsed
#1.71 0.17 1.89
vector = values
; या आप वेक्टर = वेक्टर + मान कर सकते हैं। लेकिन मुझे आपके उपयोग के मामले में गलतफहमी हो सकती है