¿Cómo se escribe (y ejecuta) un micro-benchmark correcto en Java?
Estoy buscando algunos ejemplos de código y comentarios que ilustren varias cosas en las que pensar.
Ejemplo: ¿Debería el punto de referencia medir el tiempo / iteración o iteraciones / tiempo, y por qué?
Relacionado: ¿Es aceptable la evaluación comparativa del cronómetro?
Consejos sobre cómo escribir micro evaluaciones comparativas de los creadores de Java HotSpot :
Regla 0: lea un documento de buena reputación sobre JVM y micro-benchmarking. Uno bueno es Brian Goetz, 2005 . No espere demasiado de los micro-benchmarks; miden solo un rango limitado de características de rendimiento de JVM.
Regla 1: Incluya siempre una fase de preparación que ejecute su kernel de prueba hasta el final, suficiente para activar todas las inicializaciones y compilaciones antes de la (s) fase (s) de tiempo. (Menos iteraciones está bien en la fase de calentamiento. La regla general es varias decenas de miles de iteraciones de bucle interno).
Regla 2: Siempre ejecuta con -XX:+PrintCompilation
, -verbose:gc
, etc., para que pueda verificar que el compilador y otras partes de la JVM no están haciendo un trabajo inesperado durante su fase de temporización.
Regla 2.1: Imprima mensajes al principio y al final de las fases de cronometraje y calentamiento, para que pueda verificar que no hay salida de la Regla 2 durante la fase de cronometraje.
Regla 3: tenga en cuenta la diferencia entre -client
y -server
, y OSR y las compilaciones regulares. La -XX:+PrintCompilation
bandera informa compilaciones OSR con un signo en para denotar el punto de entrada no inicial, por ejemplo: Trouble$1::run @ 2 (41 bytes)
. Prefiera el servidor al cliente, y regular a OSR, si busca el mejor rendimiento.
Regla 4: tenga en cuenta los efectos de la inicialización. No imprima por primera vez durante su fase de temporización, ya que la impresión carga e inicializa las clases. No cargue nuevas clases fuera de la fase de preparación (o fase de informe final), a menos que esté probando la carga de clases específicamente (y en ese caso cargue solo las clases de prueba). La regla 2 es su primera línea de defensa contra tales efectos.
Regla 5: Tenga en cuenta los efectos de desoptimización y recompilación. No tome ninguna ruta de código por primera vez en la fase de temporización, porque el compilador puede desechar y recompilar el código, basándose en una suposición optimista anterior de que la ruta no se usaría en absoluto. La regla 2 es su primera línea de defensa contra tales efectos.
Regla 6: Utilice las herramientas adecuadas para leer la mente del compilador y espere sorprenderse con el código que produce. Inspeccione el código usted mismo antes de formar teorías sobre qué hace que algo sea más rápido o más lento.
Regla 7: Reduce el ruido en tus medidas. Ejecute su punto de referencia en una máquina silenciosa y ejecútelo varias veces, descartando valores atípicos. Úselo -Xbatch
para serializar el compilador con la aplicación y considere la posibilidad de configurar -XX:CICompilerCount=1
para evitar que el compilador se ejecute en paralelo consigo mismo. Haga todo lo posible para reducir la sobrecarga de GC, establezca Xmx
(lo suficientemente grande) iguales Xms
y utilícelo UseEpsilonGC
si está disponible.
Regla 8: use una biblioteca para su punto de referencia, ya que probablemente sea más eficiente y ya se depuró con este único propósito. Como JMH , Caliper o los excelentes puntos de referencia UCSD de Bill y Paul para Java .
Sé que esta pregunta ha sido marcada como respondida, pero quería mencionar dos bibliotecas que nos ayudan a escribir micro benchmarks.
Caliper de Google
Tutoriales de introducción
JMH de OpenJDK
Tutoriales de introducción
Las cosas importantes para los puntos de referencia de Java son:
System.gc()
entre iteraciones, es una buena idea ejecutarlo entre pruebas, para que cada prueba obtenga un espacio de memoria "limpio" con el que trabajar. (Sí, gc()
es más una pista que una garantía, pero es muy probable que realmente se acumule basura en mi experiencia).Estoy en el proceso de escribir en un blog sobre el diseño de un marco de evaluación comparativa en .NET. Tengo un par de publicaciones anteriores que pueden darle algunas ideas; no todo será apropiado, por supuesto, pero algunas pueden serlo.
jmh es una adición reciente a OpenJDK y ha sido escrito por algunos ingenieros de rendimiento de Oracle. Ciertamente vale la pena echarle un vistazo.
El jmh es un arnés de Java para construir, ejecutar y analizar puntos de referencia nano / micro / macro escritos en Java y otros lenguajes dirigidos a la JVM.
Piezas de información muy interesantes enterradas en los comentarios de las pruebas de muestra .
Ver también:
¿Debería el punto de referencia medir el tiempo / iteración o iteraciones / tiempo, y por qué?
Depende de lo que intente probar.
Si está interesado en la latencia , use tiempo / iteración y si está interesado en el rendimiento , use iteraciones / tiempo.
Si está tratando de comparar dos algoritmos, haga al menos dos puntos de referencia para cada uno, alternando el orden. es decir:
for(i=1..n)
alg1();
for(i=1..n)
alg2();
for(i=1..n)
alg2();
for(i=1..n)
alg1();
He encontrado algunas diferencias notables (5-10% a veces) en el tiempo de ejecución del mismo algoritmo en diferentes pases.
Además, asegúrese de que n sea muy grande, de modo que el tiempo de ejecución de cada bucle sea de al menos 10 segundos más o menos. Cuantas más iteraciones, más cifras significativas en su tiempo de referencia y más confiables son los datos.
Asegúrese de utilizar de alguna manera los resultados que se calculan en código comparativo. De lo contrario, su código se puede optimizar.
Existen muchas trampas posibles para escribir micro-benchmarks en Java.
Primero: Hay que calcular con todo tipo de eventos que toman tiempo más o menos aleatorio: recolección de basura, efectos de caché (de SO para archivos y de CPU para memoria), IO, etc.
Segundo: no puede confiar en la precisión de los tiempos medidos para intervalos muy cortos.
Tercero: la JVM optimiza su código mientras se ejecuta. Por lo tanto, diferentes ejecuciones en la misma instancia de JVM serán cada vez más rápidas.
Mis recomendaciones: Haga que su punto de referencia se ejecute unos segundos, eso es más confiable que un tiempo de ejecución de milisegundos. Caliente la JVM (significa ejecutar el punto de referencia al menos una vez sin medir, que la JVM puede ejecutar optimizaciones). Y ejecute su punto de referencia varias veces (tal vez 5 veces) y tome el valor mediano. Ejecute cada micro-benchmark en una nueva instancia de JVM (llame para cada nuevo Java de benchmark) de lo contrario, los efectos de optimización de la JVM pueden influir en las pruebas en ejecución posteriores. No ejecute cosas que no se ejecuten en la fase de calentamiento (ya que esto podría desencadenar la carga de clases y la recompilación).
También debe tenerse en cuenta que también podría ser importante analizar los resultados del micro benchmark al comparar diferentes implementaciones. Por lo tanto , debe realizarse una prueba de significancia .
Esto se debe a que la implementación A
puede ser más rápida durante la mayoría de las ejecuciones del punto de referencia que la implementación B
. Pero A
también puede tener un diferencial más alto, por lo que el beneficio de rendimiento medido de A
no será de importancia en comparación con B
.
Por lo tanto, también es importante escribir y ejecutar un micro benchmark correctamente, pero también analizarlo correctamente.
Para agregar a los otros excelentes consejos, también tendré en cuenta lo siguiente:
Para algunas CPU (por ejemplo, la gama Intel Core i5 con TurboBoost), la temperatura (y el número de núcleos que se utilizan actualmente, así como su porcentaje de utilización) afecta la velocidad del reloj. Dado que las CPU se sincronizan dinámicamente, esto puede afectar sus resultados. Por ejemplo, si tiene una aplicación de un solo subproceso, la velocidad máxima del reloj (con TurboBoost) es más alta que para una aplicación que usa todos los núcleos. Por lo tanto, esto puede interferir con las comparaciones de rendimiento de subprocesos únicos y múltiples en algunos sistemas. Tenga en cuenta que la temperatura y los voltajes también afectan el tiempo que se mantiene la frecuencia Turbo.
Quizás un aspecto más fundamentalmente importante sobre el que tiene control directo: ¡asegúrese de que está midiendo lo correcto! Por ejemplo, si está utilizando System.nanoTime()
para comparar un fragmento de código en particular, coloque las llamadas a la tarea en lugares que tengan sentido para evitar medir cosas que no le interesan. Por ejemplo, no lo haga:
long startTime = System.nanoTime();
//code here...
System.out.println("Code took "+(System.nanoTime()-startTime)+"nano seconds");
El problema es que no obtiene inmediatamente la hora de finalización cuando el código ha finalizado. En su lugar, intente lo siguiente:
final long endTime, startTime = System.nanoTime();
//code here...
endTime = System.nanoTime();
System.out.println("Code took "+(endTime-startTime)+"nano seconds");
http://opt.sourceforge.net/Java Micro Benchmark: tareas de control necesarias para determinar las características de rendimiento comparativas del sistema informático en diferentes plataformas. Se puede utilizar para orientar las decisiones de optimización y comparar diferentes implementaciones de Java.
La estrella de HGTV, Christina Hall, revela que le diagnosticaron envenenamiento por mercurio y plomo, probablemente debido a su trabajo como manipuladora de casas.
Recientemente salió a la luz un informe policial que acusa a la estrella de 'Love Is Blind', Brennon, de violencia doméstica. Ahora, Brennon ha respondido a los reclamos.
Conozca cómo Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia mientras organizaba la primera celebración de Acción de Gracias desde que murió su madre, Naomi Judd.
Descubra por qué un destacado experto en lenguaje corporal cree que es fácil trazar "tales paralelismos" entre la princesa Kate Middleton y la princesa Diana.
Los inodoros arrojan columnas de aerosol invisibles con cada descarga. ¿Como sabemos? La prueba fue capturada por láseres de alta potencia.
Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?
The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!
¿Sigue siendo efectivo ese lote de repelente de insectos que te quedó del verano pasado? Si es así, ¿por cuánto tiempo?
¿Quiere probar un cepillo de dientes Sonicare sin gastar mucho dinero en uno de sus modelos favoritos de gama alta? Puede comprar un kit de la Serie 2 o Serie 3 por tan solo $ 30 hoy en Amazon. Haga clic aquí para ver la lista completa de modelos elegibles y tenga en cuenta que se descontarán $ 10 adicionales en su carrito.
Tapas elásticas de silicona de Tomorrow's Kitchen, paquete de 12 | $14 | Amazonas | Código promocional 20OFFKINJALids son básicamente los calcetines de la cocina; siempre perdiéndose, dejando contenedores huérfanos que nunca podrán volver a cerrarse. Pero, ¿y si sus tapas pudieran estirarse y adaptarse a todos los recipientes, ollas, sartenes e incluso frutas en rodajas grandes que sobran? Nunca más tendrás que preocuparte por perder esa tapa tan específica.
Hemos pirateado algunas ciudades industriales en esta columna, como Los Ángeles y Las Vegas. Ahora es el momento de una ciudad militar-industrial-compleja.
Un minorista está enlatando su sección de tallas grandes. Pero no están tomando la categoría solo en línea o descontinuándola por completo.
El equipo está a la espera de las medallas que ganó en los Juegos Olímpicos de Invierno de 2022 en Beijing, ya que se está resolviendo un caso de dopaje que involucra a la patinadora artística rusa Kamila Valieva.
Miles de compradores de Amazon recomiendan la funda de almohada de seda Mulberry, y está a la venta en este momento. La funda de almohada de seda viene en varios colores y ayuda a mantener el cabello suave y la piel clara. Compre las fundas de almohada de seda mientras tienen hasta un 46 por ciento de descuento en Amazon
El jueves se presentó una denuncia de delito menor amenazante agravado contra Joe Mixon.
El Departamento de Policía de Lafayette comenzó a investigar a un profesor de la Universidad de Purdue en diciembre después de recibir varias denuncias de un "hombre sospechoso que se acercaba a una mujer".
Al igual que el mundo que nos rodea, el lenguaje siempre está cambiando. Mientras que en eras anteriores los cambios en el idioma ocurrían durante años o incluso décadas, ahora pueden ocurrir en cuestión de días o incluso horas.
Estoy de vuelta por primera vez en seis años. No puedo decirte cuánto tiempo he estado esperando esto.
“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.
Creo, un poco tarde en la vida, en dar oportunidades a la gente. Generosamente.