예를 들어 결과를 얻는 데 필요한 반복 횟수를 모르는 경우 루프를 사용해야하는 경우가 있습니다. while 루프를 예로 들어 보겠습니다. 다음은 피해야 할 방법입니다.
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
R은 벡터가 추가 될 때마다 벡터를 복사하기 때문에 매우 비효율적입니다.
추가하는 가장 효율적인 방법은 인덱스를 사용하는 것입니다. 이번에는 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
; 또는 vector = vector + values를 수행 할 수 있습니다. 그러나 귀하의 사용 사례를 오해 할 수도 있습니다