java - resource - ¿Usar FloatMath o Math y un molde?
float vs double java (4)
En la última actualización de la API de Android, FloatMath
está marcado con la siguiente advertencia de pelusa:
En versiones anteriores de Android, se recomendaba usar android.util.FloatMath por motivos de rendimiento cuando se operaba en flotadores. Sin embargo, en hardware moderno los dobles son tan rápidos como float (aunque toman más memoria), y en versiones recientes de Android, FloatMath es en realidad más lento que usar java.lang.Math debido a la forma en que el JIT optimiza java.lang.Math . Por lo tanto, debe usar Matemáticas en lugar de FloatMath si solo está apuntando a Froyo y más arriba.
También se menciona here que el doble y el flotante tienen la misma velocidad en el hardware reciente.
Estoy usando algunas matemáticas trigonométricas en una aplicación en la que estoy trabajando actualmente (dirigida a Froyo y más arriba), pero no es necesaria una gran precisión, así que he estado usando flotadores y FloatMath
hasta el momento, y no hay necesidad de cambiar a dobles.
Sin embargo, la FloatMath
"utilizar Math
sobre FloatMath
" no dice cuál usar si float es el resultado deseado.
Entonces, en resumen; cuál es preferible?
float foo = FloatMath.sin(bar);
o
float foo = (float) Math.sin(bar);
En una nota lateral, solo tengo un dispositivo Froyo, así que no puedo hacer ningún benchmarking adecuado por mi cuenta.
A partir del nivel API 22, la clase FloatMath ha quedado en desuso en favor de la clase regular de matemáticas.
Como puede ver en los resultados a continuación, usar java.lang.Math es más rápido para flotantes que para dobles, y más rápido que FloatMath. Además, FloatMath no tiene .exp () o .pow () antes del API nivel 17.
En un Samsung GT_i9295 (4.2.2), 2 ^ 24 ciclos
Math.exp(D) Total: 7405 ms, Per Op: 0.0004414 ms
(F)Math.exp(F) Total: 5153 ms, Per Op: 0.0003071 ms
FloatMath.exp(F) Total: 8533 ms, Per Op: 0.0005086 ms
No hay datos para Math.sin en el Samsung porque al azar ha decidido ignorar Log.d ()> :(
En un HTC Hero_HT99VL (2.3.7), 2 ^ 12 ciclos
Math.sin(D) Total: 42 ms, Per Op: 0.0102539 ms
(F)Math.sin(F) Total: 33 ms, Per Op: 0.0080566 ms
FloatMath.sin(F) Total: 38 ms, Per Op: 0.0092773 ms
Math.exp(D) Total: 56 ms, Per Op: 0.0136719 ms
(F)Math.exp(F) Total: 47 ms, Per Op: 0.0114746 ms
FloatMath.exp (), .pos () y .hypot () requieren un nivel de API 17
Estaba investigando el mismo problema recientemente y encontré este informe de error sobre el problema. Las funciones Math
superan a las de FloatMath
en un orden de magnitud, como se muestra en la siguiente cita:
Usando DDMS, perfilé el código en cuestión. Cada una de las siguientes funciones se llamaron más de 100x.
Name | Cpu Time / Call
----------------------------------------------
java/lang/Math.sin (D)D | 0.005
java/lang/Math.cos (D)D | 0.007
java/lang/Math.sqrt (D)D | 0.004
android/util/FloatMath.sin | 0.017
android/util/FloatMath.cos | 0.017
android/util/FloatMath.sqrt | 0.016
Si sigue los cambios de documentación en el árbol de AOSP verá here que las funciones de Math
son preferidas a FloatMath
en las versiones de Android con un JIT, que es básicamente cualquier cosa desde Froyo (2.2) en adelante.
Los FloatMath dicen:
Rutinas de matemática similares a las encontradas en Matemáticas. Realiza cálculos en valores float directamente sin incurrir en la sobrecarga de conversiones hacia y desde el doble.
y tu cita dice:
Se recomienda usar android.util.FloatMath por motivos de rendimiento cuando se trabaja con flotadores.
Presumiblemente, el beneficio de FloatMath
siempre fue específicamente para cuando quiere un float
, pero este beneficio ahora ha sido negado.
Entonces usa:
float foo = (float) Math.sin(bar);
También considere que si el rendimiento es tan crítico que debe preocuparse por esto, quizás el cambio al double
esté garantizado después de todo (para no incurrir en el costo de la conversión).
Si el rendimiento es tan importante, entonces probablemente no desee perder el tiempo para lanzar desde y hacia double
cada vez que calcule algo.
Tal como lo entiendo, en flotadores de hardware más antiguos era más rápido que en dobles, por lo que necesitabas una biblioteca Math para flotadores. Ahora, " en hardware moderno, los dobles son tan rápidos como float ", por lo tanto, debes usar el Math
predeterminado con dobles.
Si para su aplicación es importante que los valores sean flotantes (por ejemplo, debido al consumo de memoria), debe continuar utilizando FloatMath, porque float foo = (float) Math.sin(bar);
se volverá molesto si lo usas mucho.