2012-04-28 17 views
6

Siempre me han molestado un poco por la falta de precisión Veo marcas de banco con system.time y rbenchmark (en que la precisión del tiempo puede no existir) y vi referencia Hadley el paquete microbenchmark recientemente. Así que decidí darle un giro como se ve a continuación. Me enfrenté mean contra f <- function(x) {sum(x)/length(x)} y esperaba mean para hacer mucho mejor que f pero los resultados, tal como los entiendo, no indican que esto sea cierto.resultados inesperados: microbenchmark

  1. ¿Entiendo mal los resultados?
  2. ¿Es f realmente más rápido que malo?
  3. ¿Está microbenchmark todavía en fase beta y necesita plancharse ?

Estoy ejecutando R2.15 en una máquina de ganar 7 (como microbenchmark hace los tiempos de forma diferente dependiendo de su sistema operativo).

Los resultados

Unit: microseconds 
    expr min  lq median  uq max 
1 f(x) 19.130 20.529 20.529 20.996 286.00 
2 mean(x) 28.927 29.860 30.327 30.327 672.31 

El Código

library(microbenchmark) 

x <- 1:10000 
f <- function(x) {sum(x)/length(x)} 
mean(x) 

res <- microbenchmark(
    mean(x), 
    f(x), 
times=1000L) 

print(res) 
boxplot(res) 
+0

Me gusta 'microbenchmark'. Si está haciendo más de uno o dos resultados, el trazado puede ser de gran ayuda, pero la salida predeterminada es un poco desagradable. Escribí una función autoplot para ggplot2 que puede aparecer en una de estas versiones (compruebe github mientras tanto). Ejemplos: http://stackoverflow.com/a/6919493/636656 –

+0

Esto puede explicarlo http://radfordneal.wordpress.com/2014/02/02/inaccurate-results-from-microbenchmark/ – Momo

+0

Probablemente no como todas las estadísticas para el 'f' eran más bajos y un diagrama de dispersión indicó esto también. joran clavó este. –

Respuesta

8

Podría estar equivocado, pero esto no parece tan sorprendente para mí. Antes de mean.default puede llamar al .Internal(mean(x)) tiene que verificar 3 if declaraciones, calcular la longitud de x, y luego verificar otra if declaración. Y la diferencia en veces es bastante pequeña.

Calling .Internal(mean(x) es directamente ligeramente más rápido aún:

library(microbenchmark) 

x <- 1:10000 
f1 <- function(x) {sum(x)/length(x)} 
f2 <- function(x) {.Internal(mean(x))} 

res <- microbenchmark(
    mean(x), 
    f1(x), 
    f2(x), 
times=1000L) 

print(res) 

Unit: microseconds 
    expr min  lq median  uq  max 
1 f1(x) 32.195 32.4605 32.8850 33.4645 106.997 
2 f2(x) 21.840 22.0580 22.2015 22.6270 55.316 
3 mean(x) 35.393 35.9840 36.1860 36.4420 91.203 
+0

Gracias. Hice una suposición y no la verifiqué. Una mejor comprobación de microbenchmarking sería 'suma' contra una versión' Reducir': 'suma2 <- función (x) Reducir (" + ", x)' que produce los resultados esperados. Creo que me va a gustar 'microbenchmark' –

+1

Solo encontré esto en lecturas no relacionadas. Aparentemente, la mala es algo notoria: http: //lookingatdata.blogspot.se/2011/04/speeding-up-r-computations.html –

2

creo que usted encontrará que si se golpea el tamaño de X por un factor de 10 verás los resultados más consistentes. Para ser honesto, me sorprendería si realmente puedes obtener una precisión de sincronización de micro segundos en una computadora con un sistema operativo multitarea.

También puede considerar:

  • ¿Está ejecutando en un ordenador portátil o una máquina que tiene la escala automática frecuencia de la CPU?
  • ¿Calentamiento?
  • Fijando su proceso a un núcleo.
+0

Parte de la belleza de 'microbenchmark' es que ejecuta cosas muchas veces para que pueda ver cómo varían los resultados, así que supongo que lo que está funcionando en el fondo no tiene ningún efecto en los resultados en la expectativa. –

+0

@ gsk3 eche un vistazo a los tiempos de salida, y verá una cola larga, algo así como ... hist (res [res $ expr == 'f (x)', 'time']/length (x), breaks = 90) – Sean

+0

Claro, pero la mediana es probablemente una estimación bastante buena, ¿no? –

Cuestiones relacionadas