2014-12-08 9 views
6

Mi stavo chiedendo quanto sia più veloce a!=0 sia di !a==0 e utilizzassi il microbenchmark del pacchetto R. Ecco il codice (ridurre 3E6 e 100 se il vostro pc è lento):Tempo di calcolo! =

library("microbenchmark") 
a <- sample(0:1, size=3e6, replace=TRUE) 
speed <- microbenchmark(a != 0, ! a == 0, times=100) 
boxplot(speed, notch=TRUE, unit="ms", log=F) 

Ogni volta, ottengo una trama come quella qui sotto. Come previsto, la prima versione è più veloce (in media 26 millisecondi) rispetto alla seconda (33 ms).

Ma da dove provengono questi valori molto alti (valori anomali)? È un qualche effetto di gestione della memoria? Se imposto i tempi su 10, non ci sono valori anomali ...

Modifica: sessionInfo(): R versione 3.1.2 (2014-10-31) Piattaforma: x86_64-w64-mingw32/x64 (64-bit)

computation time unequal and not_equal

+2

Non credo che questo sta per essere facile da rintracciare; Ho visto risultati simili anche con 'times = 10' o giù di lì. Tieni presente che 'microbenchmark' non è a prova di proiettile. Ci sono un paio di blog da qualche parte che indicano i semibugs nel modo in cui raccolgono informazioni sui tempi. Può anche essere semplicemente che qualche altra "cosa" accade di tanto in tanto durante il normale corso delle operazioni di 'R' - una chiamata' gc', o in attesa di riallocazione della RAM a livello di sistema, ecc. Forse prova ad eseguire un ciclo intorno 'system.time' per vedere quale è la distribuzione dei risultati? –

risposta

2

Tu dici che non si dispone di valori anomali quando times=10, ma esegue microbenchmark con times=10 più volte e si rischia di vedere il valore anomalo dispari. Ecco un confronto di una corsa di con dieci esecuzioni di times=10, che mostra che i valori anomali si verificano in entrambe le situazioni.

A seconda delle dimensioni degli oggetti coinvolti nell'espressione, immagino potrebbero sorgere valori anomali quando la macchina è in difficoltà con i limiti di memoria, ma potrebbero verificarsi anche a causa della tensione della CPU, ad es. a causa di processi non R.

a <- sample(0:1, size=3e6, replace=TRUE) 
speed1 <- microbenchmark(a != 0, ! a == 0, times=100) 
speed1 <- as.data.frame(speed1) 

speed2 <- replicate(10, microbenchmark(a != 0, ! a == 0, times=10), simplify=FALSE) 
speed2 <- do.call(rbind, lapply(speed2, cbind)) 

times <- cbind(rbind(speed1, speed2), method=rep(1:2, each=200)) 
boxplot(time ~ expr + method, data=times, 
     names=c('!=; 1x100', '!==; 1x100', '!=; 10x10', '!==; 10x10')) 

enter image description here

+0

A questo livello di risoluzione, penso che i valori anomali siano quasi sempre il risultato della garbage collection – hadley

0

penso che il confronto è slighlty ingiusto. Ovviamente si otterrebbero valori anomali, il tempo di calcolo dipende da diversi fattori (garbage collection, risultati memorizzati nella cache, ecc.) Quindi non è davvero una sorpresa. Stai utilizzando lo stesso vettore a in tutti i benchmark, quindi il caching avrebbe sicuramente un ruolo.

Ho regolato un po 'il processo randomizzando il a variabile prima del calcolo, e ho ottenuto risultati relativamente comparabili:

library("microbenchmark") 
do.not<-function() { 
    a <- sample(0:1, size=3e6, replace=TRUE) 
    a!=0; 
} 

do<-function() { 
    a <- sample(0:1, size=3e6, replace=TRUE) 
    a==0; 
} 

randomize <- function() { 
    a <- sample(0:1, size=3e6, replace=TRUE) 
} 


speed <- microbenchmark(randomize(), do.not(), do(), times=100) 
boxplot(speed, notch=TRUE, unit="ms", log=F) 

Boxplot

ho aggiunto anche la funzione sample come punto di riferimento e vedere quanto è "volatile".

Personalmente non sono sorpreso dai valori anomali. Inoltre, anche se si esegue lo stesso benchmark per size=10, si ottengono ancora valori anomali. Essi non sono una conseguenza del calcolo, ma della condizione complessiva del PC (altri script in esecuzione, carico di memoria, ecc)

Grazie

+2

Si confronti '! =' E '=='.Il diverso timing è il risultato di una chiamata aggiuntiva a '!' In '! (A == 0)'. – Roland

Problemi correlati