Manchmal müssen wir Schleifen verwenden, wenn wir beispielsweise nicht wissen, wie viele Iterationen wir benötigen, um das Ergebnis zu erhalten. Nehmen Sie als Beispiel while-Schleifen. Nachfolgend finden Sie Methoden, die Sie unbedingt vermeiden sollten:
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
Diese sind sehr ineffizient, da R den Vektor jedes Mal kopiert, wenn er angehängt wird.
Der effizienteste Weg zum Anhängen ist die Verwendung des Index. Beachten Sie, dass ich es diesmal 1e7 Mal iterieren lasse, aber es ist immer noch viel schneller als c
.
a=numeric(0)
system.time(
{
while(length(a)<1e7){
a[length(a)+1]=pi
}
}
)
# user system elapsed
# 5.71 0.39 6.12
Das ist akzeptabel. Und wir können es ein bisschen schneller machen durch den Austausch [
mit [[
.
a=numeric(0)
system.time(
{
while(length(a)<1e7){
a[[length(a)+1]]=pi
}
}
)
# user system elapsed
# 5.29 0.38 5.69
Vielleicht haben Sie bereits bemerkt, dass length
dies zeitaufwändig sein kann. Wenn wir durch length
einen Zähler ersetzen :
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
Wie andere Benutzer bereits erwähnt haben, ist die Vorabzuweisung des Vektors sehr hilfreich. Dies ist jedoch ein Kompromiss zwischen Geschwindigkeit und Speichernutzung, wenn Sie nicht wissen, wie viele Schleifen Sie benötigen, um das Ergebnis zu erhalten.
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
Eine Zwischenmethode besteht darin, nach und nach Ergebnisblöcke hinzuzufügen.
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
; oder Sie könnten vector = vector + values tun. Aber ich könnte Ihren Anwendungsfall falsch verstehen