Проблема вызвана главным образом тем, что вы объединяете постоянно растущую строку teststring
с новой подстрокой в каждом раунде. Результатом является экспоненциально растущее время выполнения. Этот эффект усугублялся использованием целого data.frame на каждом шаге, а также строкой print(i)
. Их исправление значительно ускорит код.
На моей машине с 10000 строками в expectedOutput
это занимает 6-7 секунд, для 50000 строк это занимает 2 минуты, для 100000 строк это занимает 6-7 минут и для 200000 строк требуется 24-25 минут для запуска исходного кода ниже. Это может быть уменьшено до 3-4 секунд для 50000 строк и всего лишь 11-12 секунд для 200000 строк с шагами, следующими за ним.
Сначала я смоделировал некоторые данные для теста:
expectedOutput <- cbind(
db_col_name = c(paste0("A-", c(paste0("0", c(paste0("0", c(paste0("0", 0:9), 10:99)),
100:999)), 1000:9999)),
paste0("B-", c(paste0("0", c(paste0("0", c(paste0("0", 0:9), 10:99)),
100:999)), 1000:9999)),
paste0("C-", c(paste0("0", c(paste0("0", c(paste0("0", 0:9), 10:99)),
100:999)), 1000:9999)),
paste0("D-", c(paste0("0", c(paste0("0", c(paste0("0", 0:9), 10:99)),
100:999)), 1000:9999)),
paste0("E-", c(paste0("0", c(paste0("0", c(paste0("0", 0:9), 10:99)),
100:999)), 1000:9999))),
data.frame(replicate(100, sample(0:1000, 50000, rep=TRUE))))
uniqueCol <- "COLUMN_NAME"
Код был запущен для начального теста:
teststring <- paste(uniqueCol," in (", sep = "")
i <- 1
while(i < nrow(expectedOutput)){
if(i %% 1000 == 0){
teststring <- substr(teststring, 1, nchar(teststring) - 1)
teststring <- paste(teststring, ") OR ", uniqueCol, " in (", sep="")
}
teststring <- paste(teststring, "'", expectedOutput[i, 1], "',", sep="")
print(i)
i <- i + 1
}
Удаление print(i)
сократило время работы примерно на 1,6 минуты для 50000 строк.
Объединение подстрок в 1000 шагов, затем сохранение их в векторе, затем конкатенация вектора в конце значительно сократило время выполнения: около 5-6 секунд для 50000 строк:
teststring <- character(0)
teststr_tmp <- paste(uniqueCol," in (", sep = "")
i <- 1
while(i < nrow(expectedOutput)){
if(i %% 1000 == 0){
teststr_tmp <- substr(teststr_tmp, 1, nchar(teststr_tmp) - 1)
teststr_tmp <- paste(teststr_tmp, ") OR ", uniqueCol, " in (", sep="")
teststring <- c(teststring, teststr_tmp)
teststr_tmp <- paste(uniqueCol," in (", sep = "")
}
teststr_tmp <- paste(teststr_tmp, "'", expectedOutput[i, 1], "',", sep="")
i <- i + 1
}
teststring <- paste(teststring, collapse)
Наконец, поместив первый столбец expectedOutput
в отдельный вектор дополнительно уменьшил время работы до 3-4 секунд для 50000 строк и всего 11-12 секунд для 200000 строк:
teststring <- character(0)
teststr_tmp <- paste(uniqueCol," in (", sep = "")
i <- 1
expectedOutputValues <- expectedOutput[[1]]
while(i < length(expectedOutputValues)){
if(i %% 1000 == 0){
teststr_tmp <- substr(teststr_tmp, 1, nchar(teststr_tmp) - 1)
teststr_tmp <- paste(teststr_tmp, ") OR ", uniqueCol, " in (", sep="")
teststring <- c(teststring, teststr_tmp)
teststr_tmp <- paste(uniqueCol," in (", sep = "")
}
teststr_tmp <- paste(teststr_tmp, "'", expectedOutputValues[i], "',", sep="")
i <- i + 1
}
teststring <- paste(teststring, collapse="")