2013-06-23 3 views
8

Я боюсь понять, почему этот бит кода (адаптированный из R Benchmark 2.5) становится медленнее и медленнее (в среднем) по мере увеличения количества итераций.R петля становится медленнее и медленнее

require(Matrix) 
c <- 0; 
for (i in 1:100) { 
    a <- new("dgeMatrix", x = rnorm(3250 * 3250), Dim = as.integer(c(3250, 3250))) 
    b <- as.double(1:3250) 

    invisible(gc()) 
    timing <- system.time({ 
    c <- solve(crossprod(a), crossprod(a, b)) 
    }) 
    print(timing) 

    rm(a, b, c) 
} 

Вот sample output, которая изменяется незначительно от одного прогона к другому.

Как я понимаю, ничто не должно сохраняться с одной итерации на другую, но время медленно увеличивается с 1 секунды в первые несколько циклов до более чем 4 секунд в более поздних циклах. Есть ли у вас какие-либо идеи, что вызывает это, и как я могу это исправить?

Переключение цикла for в приложение * похоже, дает аналогичные результаты.

Я знаю, что код не оптимизирован, но он исходит из широко используемого бенчмарка, и в зависимости от того, что вызывает это поведение, это может указывать на серьезное смещение в его результатах (которое по умолчанию повторяется 3 раза).

Я запускаю R версию 3.0.1 (x86_64) на Mac OS 10.8.4 с 16 ГБ оперативной памяти (многие из которых бесплатны). BLAS - это OpenBLAS.

+0

Я не могу воспроизвести это, используя очень похожую настройку. Сколько итераций требуется для замедления? – GSee

+0

На моем компьютере каждая итерация занимает ~ 30 секунд. Я сделал 10, и все они длились около 30-35 секунд. –

+0

ПК здесь. Плоская 9 секунд на итерацию. Я использую библиотеку ATLAS, которая, как я знаю, делает этот вид операций намного быстрее, по крайней мере, по сравнению с DLL BLAS, который поступает по умолчанию. Макрос OP все еще намного быстрее ... Во всяком случае, мы начинаем быть хорошей связкой, неспособной воспроизвести проблему. Возможно, OP должен рассмотреть возможность распечатки всего вывода 'system.time'. * Истекшее время * ('[3]') не всегда говорит полную историю; Возможно, пользовательское время будет лучшим выбором. – flodel

ответ

0

Возможно, вы могли бы попытаться превратить код в цикл for в функцию. Таким образом, на самом деле никто не может воздействовать на другой. Кроме того, он устраняет беспорядок, вызванный чрезмерным использованием rm() и gc().

require(Matrix) 

NewFun <- function() { 
    a <- new("dgeMatrix", x = rnorm(3250 * 3250), Dim = as.integer(c(3250, 3250))) 
    b <- as.double(1:3250) 
    timing <- system.time({ 
     c <- solve(crossprod(a), crossprod(a, b)) 
    }) 
    print(timing) 
} 

for (i in 1:100) { 
    NewFun() 
} 
1

Одним из решений было бы использовать пакет компилятора для компиляции кода в байтовый код. Это должно устранить проблемы с нечетным временем, поскольку он будет вызывать один и тот же скомпилированный код на каждой итерации. Это также должно сделать ваш код быстрее. Чтобы включить компилятор кода, включают в себя две строки ниже:

library(compiler) 
enableJIT(3) 

Если компиляции кода не устраняет проблему, то совокупность подозрительных проблем будет сужен.