sirve - ¿Por qué esta solución GoLang es más rápida que la solución Java equivalente?
para que sirve settitle en java (1)
Recientemente en el trabajo estábamos jugando con la siguiente pregunta de prueba formulada por IBM https://www.research.ibm.com/haifa/ponderthis/challenges/May2015.html
Después de un poco de esfuerzo, un colega y yo llegamos a dos soluciones, una en GoLang https://gist.github.com/walesey/e2427c28a859c4f7bc920c9af2858492#file-main-go-L57 y la otra en Java https://gist.github.com/boyter/42df7f203c0932e37980f7974c017ec5#file-puzzle-java-L63 con el método de rendimiento crítico tanto para jugar como juegos en Java y juego en GoLang (ambos vinculados anteriormente).
El programa Go es casi una copia literal de Java, y sin embargo su tiempo de ejecución es ~ 6 segundos, mientras que el de Java es aproximadamente ~ 26 segundos (en mi máquina local). Números similares fueron replicados en algunas otras máquinas con el programa Go siendo aproximadamente ~ 5 veces más rápido.
El programa Go se compila utilizando 1.7.5 y Java utilizando la versión 1.8.0_65, ambos ejecutados en macOS Sierra 10.12.3 en una MacBook Pro retina de finales de 2013 con una CPU i5 de 2.6GHz.
¿Por qué el programa Go es 5 veces más rápido que el de Java cuando la mayoría de los puntos de referencia indican que Java debería tener el mismo tiempo de ejecución? Es solo matemática básica en un bucle, así que parece que deberían ejecutarse casi al mismo tiempo. Pude entender un segundo más o menos para la hora de inicio de JVM, pero parece que no.
Ambos programas usan prácticamente el mismo ciclo. Todas las posibles permutaciones de los resultados del juego se crean y se repiten para cada cantidad inicial de dinero. Simplemente parece que para cualquier número de operaciones de bucle en el bucle principal que Go está ejecutando suena alrededor de Java.
Entiendo que este es un punto de referencia "micro", pero me pregunto por qué exactamente el código Go está superando enormemente el código de Java. ¿Es solo que Go for simple loops / math es más eficiente y, por lo tanto, más rápido? ¿Es capaz de desenrollar el bucle quizás (aunque parece poco probable que produzca una diferencia tan grande)?
Si no, ¿cómo debería estructurar un programa Java para obtener el máximo rendimiento de un simple bucle y operación matemática?
EDITAR - Gracias a Dolda2000 modifiqué la versión de Java. Ahora es aproximadamente la misma velocidad que la versión de GoLang. De hecho, el problema fue que los juegos se crearon y la versión de Java tuvo que simular más juegos para determinar si el juego fue lo suficientemente largo. Con los cambios se está ejecutando en aproximadamente ~ 6 segundos y ha restaurado mi fe en Java.
Actualización : aquí hay un ensayo ampliado que analiza los antecedentes de esta pregunta con más detalle.
Como resultado, tus programas no son tan iguales como crees que son. Los instrumentaba para ver cuántos juegos (es decir, rondas de apuestas individuales) simulaban, y mientras la versión Go simulaba 1 612 629 805 juegos, la versión de Java simulaba 12 323 903 502 juegos, casi un orden de magnitud más.
En mi máquina, apagando el multihilo para obtener resultados más predecibles, el programa Java se activó unos 75 segundos, y el programa Go en 12.5 segundos. Coincidiendo eso con el tiempo de ejecución total, parece que el programa Java es en realidad un poco más rápido por juego simulado, alrededor de 6.1 ns, en comparación con 7.8 ns para el programa Go.
Sin embargo, aún no estoy seguro de por qué simulan números tan diferentes de juegos. Quizás la forma en que la versión Go genera las rondas simplemente sucede para encontrar terminaciones mucho más rápidas.
EDITAR : En realidad, esa última suposición tiene mucho sentido. La versión Go comienza modulando las rondas iniciales de un juego, mientras que la versión de Java comienza modulando las últimas rondas de un juego (en otras palabras, mirando la lista de rondas como una lista de 11 dígitos de base-3) números, la versión Go es little-endian, mientras que la versión Java es big-endian, por así decirlo), por lo que la versión Java tendrá que simular a través de muchos más inicios idénticos para llegar a las variaciones que terminan. No he intentado verificar esta hipótesis, pero estoy seguro de que no siento la necesidad de hacerlo.