Warum ist die zeitliche Komplexität dieser Schleife nicht linear?

Warum ist die zeitliche Komplexität dieser Schleife nicht linear und warum ist sie so langsam? Die Schleife dauert~38s for N=50k, und~570s for N=200k. Gibt es einen schnelleren Weg, dies zu tun?Rprof() scheint darauf hinzudeuten, dass das Schreiben in den Speicher sehr langsam ist.

df <- data.frame(replicate(5, runif(200000)))
df[,1:3] <- round(df[,1:3])

Rprof(line.profiling = TRUE); timer <- proc.time()
x <- df; N <- nrow(df); i <- 1 
ind <- df[1:(N-1),1:3] == df[2:N,1:3]; 
rind <- which(apply(ind,1,all))
N <- length(rind)
while(i <= N)
{
    x$X4[rind[i]+1] <- x$X4[rind[i]+1] + x$X4[rind[i]]
    x$X5[rind[i]+1] <- x$X4[rind[i]+1] * x$X3[rind[i]+1]
    x$X5[rind[i]+1] <- trunc(x$X5[rind[i]+1]*10^8)/10^8
    x$X1[rind[i]] <- NA
    i <- i + 1
};x <- na.omit(x)
proc.time() - timer; Rprof(NULL)
summaryRprof(lines = "show")

Der Zweck dieses Algorithmus besteht darin, den Datenrahmen zu durchlaufen und benachbarte Zeilen zu kombinieren, die auf bestimmten Elementen übereinstimmen. Das heißt, es wird eine der Zeilen entfernt und einige der Werte dieser Zeile zur anderen Zeile hinzugefügt. Der resultierende Datenrahmen sollte n weniger Zeilen haben, wobei n die Anzahl übereinstimmender benachbarter Zeilen im ursprünglichen Datenrahmen ist. Jedes Mal, wenn ein Zeilenpaar kombiniert wird, werden der Index des Quelldatenrahmens und des neuen Datenrahmens um 1 nicht synchronisiert, da eine Zeile aus dem neuen Rahmen entfernt / weggelassen wird.i verfolgt die Position im Quelldatenrahmen undq verfolgt die Position im neuen Datenrahmen.

Der obige Code wurde dank des Kommentars von @ joran aktualisiert. Die Leistung wird wesentlich verbessert, um~5.5s for N=50k und~88s for N=200k. Die zeitliche Komplexität ist jedoch immer noch nicht linear, was ich nicht verstehen kann. Ich muss dies mit N = 1 Million oder mehr ausführen, daher ist es immer noch nicht sehr schnell.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage