2014-12-08 6 views
6

Ich frage mich, wie viel schneller a!=0 ist als !a==0 und verwendet das R-Paket Microbenchmark. Hier ist der Code (reduzieren 3E6 und 100, wenn Ihr PC langsam ist):Rechenzeit! =

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) 

Jedesmal, erhalte ich eine Handlung wie die unten. Wie erwartet, ist die erste Version schneller (Median 26 Millisekunden) als die zweite (33 Millisekunden).

Aber woher kommen diese wenigen sehr hohen Werte (Ausreißer)? Ist das ein Memory-Management-Effekt? Wenn ich mal auf 10 setze, gibt es keine Ausreißer ...

Edit: sessionInfo(): R Version 3.1.2 (2014-10-31) Plattform: x86_64-w64-mingw32/x64 (64-Bit)

computation time unequal and not_equal

+2

Ich denke nicht so einfach sein wird, aufzuspüren; Ich habe ähnliche Ergebnisse gesehen, sogar mit "mal = 10" oder so. Denken Sie daran, dass "Microbenchmark" nicht kugelsicher ist. Es gibt ein paar Blogs, die irgendwo auf Semibugs hinweisen, wie es Timing-Informationen sammelt. Es kann auch einfach sein, dass während des normalen Ablaufs von "R" -Operationen gelegentlich ein "Ding" passiert - ein "GC" -Aufruf oder Warten auf RAM-Neuzuweisung auf Systemebene, etc. Versuchen Sie vielleicht, eine Schleife herumzulaufen 'system.time' um zu sehen, wie die Verteilung der Ergebnisse ist? –

Antwort

2

Sie sagen, dass Sie Ausreißer haben nicht, wann times=10, aber microbenchmark mit times=10 mehrmals laufen und Sie werden wahrscheinlich die ungeraden Ausreißer zu sehen. Hier ist ein Vergleich von einem Lauf von times=100 mit zehn Läufen von times=10, die zeigt, dass Ausreißer in beiden Situationen auftreten.

Abhängig von der Größe der Objekte, die am Ausdruck beteiligt sind, stelle ich mir vor, dass Ausreißer auftreten können, wenn Ihr Computer mit Speicherbeschränkungen kämpft, aber sie können auch aufgrund von CPU-Belastung, z. aufgrund von Nicht-R-Prozessen.

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

Bei dieser Auflösungsebene sind die Ausreißer fast immer das Ergebnis der Garbage Collection – hadley

0

Ich denke, der Vergleich slighlty unfair. Natürlich würden Sie Ausreißer bekommen, die Rechenzeit hängt von mehreren Faktoren ab (Speicherbereinigung, Cache-Ergebnisse usw.), also ist es nicht wirklich eine Überraschung. Sie verwenden den gleichen Vektor a in allen Benchmarks so Caching würde sicherlich eine Rolle spielen.

I eingestellt, um ein wenig das Verfahren durch die a Variable vor der Berechnung Randomisierung, und ich habe relativ vergleichbare Ergebnisse:

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

I auch die sample Funktion als Benchmark hinzugefügt und sehen wie 'flüchtig' das ist.

Persönlich bin ich nicht auf die Ausreißer überrascht. Auch wenn Sie denselben Benchmark für size=10 ausführen, erhalten Sie immer noch Ausreißer. Sie sind nicht eine Folge der Berechnung, sondern des gesamten PC-Zustand (andere Skripte ausgeführt wird, Speicherauslastung, usw.)

Dank

+2

Sie vergleichen '! =' Und '=='.Das unterschiedliche Timing resultiert aus einem zusätzlichen Aufruf von '!' In '! (A == 0)'. – Roland

Verwandte Themen