JUnitBenchmarks: benchmarking con JUnit4
JUnitBenchmarks es un proyecto basado en JUnit4 para crear test de rendimiento para nuestras aplicaciones Java. JUnitBenchmarks nos permite de un modo sencillo medir el tiempo de ejecución de una pieza de código, y a la vez monitorizar al recogedor de basura durante la ejecución. Además, se encarga de realizar un "calentamiento" en la máquina virtual para asegurarnos de que estamos midiendo el tiempo que realmente va a llevar ejecutar ese código una vez que el JIT haya hecho su trabajo.
JUnitBenchmarks se encuentra actualmente en su versión 0.4. Sus desarrolladores denominan esta versión como alpha, pero ya es utilizable. Aquí tenéis un tutorial, y aquí os dejo un código de ejemplo donde se trata de medir la diferencia de emplear TextBuilder y StringBuilder concatenado texto:
import com.carrotsearch.junitbenchmarks.AbstractBenchmark; import com.carrotsearch.junitbenchmarks.BenchmarkOptions; import javolution.text.TextBuilder; import org.junit.Test; /** * Benchmark for String concatenation. Compares StringBUilder (JDK) and * TextBuilder (Javolution). */ public class StringConcatenationBenchmark extends AbstractBenchmark { public static final long LOOPS_COUNT = 10000000; @Test @BenchmarkOptions(benchmarkRounds = 3, warmupRounds = 1) public void stringBuilderBenchmark() { StringBuilder builder = new StringBuilder(); for (long i = 0; i < LOOPS_COUNT; i++) { builder.append('i').append(i); } System.out.println(builder.toString().length()); } @Test @BenchmarkOptions(benchmarkRounds = 3, warmupRounds = 1) public void textBuilderBenchmark() { TextBuilder builder = new TextBuilder(); for (long i = 0; i < LOOPS_COUNT; i++) { builder.append('i').append(i); } System.out.println(builder.toString().length()); } }
Esta es la salida de consola que nos proporciona JUnitBenchmarks con este test:
StringConcatenationBenchmark.stringBuilderBenchmark: [measured 3 out of 4 rounds, threads: 1 (sequential)] round: 0.68[+- 0.06], round.block: 0.00 [+- 0.00], round.gc: 0.00 [+- 0.00], GC.calls: 6, GC.time: 0.19, time.total: 2.66, time.warmup: 0.64, time.bench: 2.03 StringConcatenationBenchmark.textBuilderBenchmark: [measured 3 out of 4 rounds, threads: 1 (sequential)] round: 0.47 [+- 0.01], round.block: 0.00 [+- 0.00], round.gc: 0.00 [+- 0.00], GC.calls: 5, GC.time: 0.18, time.total: 1.97, time.warmup: 0.57, time.bench: 1.41
TextBuilder ha necesitado 0.47 ms, mientras que StringBuilder ha necesitado 0.68 ms.
¿Qué os parece el proyecto JUnitBenchmarks? ¿Creéis que os resultará útil?
Reader Comments (2)
Yo lo veo bastante útil para temas de rendimiento.
Por ejemplo, se me ocurre que podría utilizarlo para la siguiente prueba:
-Quiero recoger un listado de elementos paginados de una tabla de Oracle, donde tengo 1000 registros, tengo dos opciones:
1) Traigo los 1000 registros y después hago la paginación usando Java y veo cuanto tiempo tarda.
2) O bien, lanzo ya una query paginada sobre Oracle...
Y comparo tiempos, obviamente, tardará menos la opción 2), pero, ¿cuánto tiempo? Con este framework, se podría resolver rápidamente la respuesta y realizar pruebas de medición.
Un saludo,
Creo que tanto StringBuilder como TextBuilder deberían inicializarse, en sus respectivos constructores, con la capacidad inicial estimada, para poder hacer comparaciones más precisas.
En este caso, puesto que se conoce de antemano esa capacidad:
StringBuilder builder = new StringBuilder(2*LOOPS_COUNT);
TextBuilder builder = new TextBuilder(2*LOOPS_COUNT);
No tiene nada que ver con la librería; pero cuando se hacen comparaciones de rendimiento, los detalles son significativos.