Es Matemáticas.max(a,b) o (a>b)?a: b más rápido en Java?


¿Cuál es más rápido en Java y por qué?

  1. Math.max(a,b)
  2. (a>b)?a:b

(Esto fue preguntado en una entrevista.)

 23
Author: Trilarion, 2010-01-20

8 answers

Math.max(a, b) es una función estática (lo que significa que no hay sobrecarga de llamadas virtuales) y es probable que esté alineada por la JVM con las mismas instrucciones que (a > b) ? a : b.

 22
Author: dsimcha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-20 17:51:59

Aquí está el código openjdk para Math.max() en Java:

public static int max(int a, int b) {
    return (a >= b) ? a : b;
}

Por lo tanto, el código probablemente sería (casi) exactamente la misma velocidad.

(Seamos honestos, si usted está preocupado por las mejoras de velocidad a un nivel tan bajo, es probable que tenga problemas mucho mayores en su código.)

 22
Author: jjnguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-15 20:40:54

Las preguntas de rendimiento siempre requieren una prueba antes de que pueda comenzar a especular:

public static void maxtest()
{
    int res = 0;
    for( int idx = 0; --idx != 0; )
        // res = ( res > idx ) ? res : idx;
        res = Math.max( res, idx );
    System.out.println( "res: " + res );
}

Esto se ejecuta en mi máquina 6 segundos con Math.max() y 3.2 segundos con ?: en el último servidor 1.6.1 x64 Sun JVM. Así que ?: es en realidad más rápido. Contrariamente a todas las esperanzas que nos gusta poner en los JITs que realmente se han vuelto increíbles para el momento en que todavía no atrapan todo.

EDITAR: Por curiosidad también probé este código con el cliente de 32 bits JVM 1.6.1 en la misma máquina y con estas dos versiones se ejecutan en 7 segundos! Por lo tanto, probablemente no sea la invocación del método la que no se inline, pero el JIT del servidor parece ser capaz de hacer algunas optimizaciones adicionales para este caso de prueba en particular que no puede detectar cuando hay una llamada al método involucrada.

 11
Author: x4u,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-20 18:12:41

He estado en el extremo receptor de este tipo de preguntas y por lo general son más acerca de cómo responder a la pregunta que cuál es la respuesta 'correcta'.

 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-20 18:29:28

Si hubiera hecho tal pregunta en una entrevista, habría esperado que el candidato me dijera que las dos expresiones pueden no dar el mismo resultado para todos los tipos posibles de a y b.

 2
Author: jarnbjo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-20 18:29:34

La pregunta original no especifica el tipo de argumentos. Esto importa porque la definición de max (y min) para argumentos de coma flotante es más compleja. Para coma flotante (doble o flotante) la Matemática.es probable que el método max sea más lento, pero también puede devolver un resultado diferente si uno de los argumentos es NaN.

 2
Author: Mark Thornton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-20 20:26:54

No confíes en la especulación. En su lugar, benchmark su caso de uso particular.

Algunos detalles fácilmente pasados por alto en muchas de las otras respuestas:

Aunque se puede ver una fuente Java de Math.max, esto es en realidad no siempre lo que se utilizará. Este método tiene una versión intrínseca en casi todos los JRE. Ver el código fuente de Hotspot en JDK7, vmSymbols.hpp para una lista de tales intrínsecos.

Por lo que puedo decir, Hotspot intentará un número de optimizaciones cuando ve una instrucción max o min; en particular para optimizar, por ejemplo, arraycopy. Entre otros, realmente optimizará Math.max(same, same) de distancia.

En otros casos, sin embargo, puede no optimizar mucho; (a<=b)?a:b entonces puede ser más rápido. He estado comparando un poco, y de hecho a menudo me pareció que esto era más rápido. Pero YMMV, y definitivamente depende del contexto si Hotspot puede optimizar uno mejor o el otro. También variará de una versión de hotspot a otra...

 2
Author: Anony-Mousse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-30 18:11:55

No es lo mismo. Cuando está escribiendo (a > b) ? a : b no tiene una llamada a una función adicional, por lo que será más rápido. Es el equivalente a la inserción en C++. Pero esto no hará ninguna diferencia en la vida real. Math.max(a,b) es más legible, así que lo usaría.

 -2
Author: XMLDUDE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-20 17:55:27