2013-06-23 8 views
8

Non riesco a capire perché questo bit di codice (adattato da R Benchmark 2.5) diventa più lento e lento (in media) all'aumentare del numero di iterazioni.R loop sempre più lento

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) 
} 

Qui è un sample output, che varia leggermente da una corsa all'altra.

Come ho capito, niente dovrebbe essere salvato da un'iterazione all'altra, tuttavia il tempo aumenta lentamente da 1 secondo nei primi pochi loop a più di 4 secondi nei cicli successivi. Hai idea di cosa lo stia causando e come potrei risolverlo?

Il passaggio del ciclo for ad un * apply sembra fornire risultati simili.

So che il codice non è ottimizzato, ma proviene da un benchmark ampiamente utilizzato e, a seconda di cosa causa questo comportamento, potrebbe indicare un bias serio nei suoi risultati (che solo itera 3 volte per impostazione predefinita).

Sto eseguendo R versione 3.0.1 (x86_64) su Mac OS 10.8.4 con 16 GB di RAM (in abbondanza gratuita). Il BLAS è OpenBLAS.

+0

Non riesco a replicarlo utilizzando un'impostazione molto simile. Quante iterazioni ci vogliono per iniziare a rallentare? – GSee

+0

Sul mio computer, ogni iterazione dura ~ 30 secondi. Ne ho fatti 10 ed erano tutti di circa 30-35 secondi. –

+0

PC qui. Un piatto 9 secondi per iterazione. Sto usando la libreria ATLAS che conosco rende questo tipo di operazioni molto più veloce, almeno rispetto alla DLL BLAS che viene fornita di default. Il Mac di OP è ancora molto più veloce ... Ad ogni modo, stiamo iniziando a essere un buon gruppo non in grado di riprodurre il problema. Forse l'OP dovrebbe prendere in considerazione la stampa dell'intero output 'system.time'. * tempo trascorso * ('[3]') non dice sempre la storia completa; Forse * l'ora dell'utente * sarà una scelta migliore. – flodel

risposta

0

Forse si potrebbe provare a rendere il codice all'interno del ciclo for in una funzione. In questo modo non c'è davvero modo in cui una corsa potrebbe avere un impatto su un'altra. Inoltre, rimuove il disordine causato dall'uso eccessivo di rm() e 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

Una soluzione potrebbe essere quella di utilizzare il pacchetto compilatore per compilare il codice in bytecode. Ciò dovrebbe eliminare i problemi di temporizzazione dispari in quanto chiamerà lo stesso codice compilato ogni iterazione. Dovrebbe anche rendere il tuo codice più veloce. Per abilitare il compilatore sul vostro codice, includere le due righe sotto:

library(compiler) 
enableJIT(3) 

Se compilazione del codice non elimina il problema, allora l'insieme di problemi sospetti sarà ristretto.