Float o doble?

¿Cuál es más rápido, doble o flotante, al preformar arithimic (+ – * /%), y vale la pena usar float por razones de memoria? Precisión no es un problema mucho de un problema.

Siéntase libre de llamarme loco por siquiera pensar en esto. Sólo curioso como veo la cantidad de flotadores que estoy usando es cada vez mayor.

EDIT 1: La única razón de esto está bajo androide es porque es donde creo que la memoria importa; Ni siquiera pediría esto para el desarrollo de escritorio.

Yo no aconsejaría tampoco para las operaciones rápidas, pero creo que las operaciones en los flotadores sería más rápido, ya que son 32 bits vs 64 bits en dobles.

La velocidad de procesamiento en ambos tipos debería ser aproximadamente la misma en CPUs hoy en día.

"Utilizar la precisión que se requiere para obtener resultados aceptables".

Preguntas relacionadas han sido hechas un par de veces aquí en SO, aquí hay una .

Editar:

En términos de velocidad, no hay diferencia entre float y doble en el hardware más moderno.

Por favor, echa un vistazo a este artículo de developer.android.com.

Double en lugar de Float fue aconsejado por ADT v21 lint mensaje debido a la JIT (Just In Time) optimizaciones en Dalvik de Froyo en adelante (API 8 y posteriores).

Yo estaba usando FloatMath.sin y sugirió Math.sin en su lugar con lo siguiente en el menú contextual "explain issue". Me lee como un mensaje general relativo a doble vs flotante y no sólo trig relacionados.

"En las versiones más antiguas de Android, el uso de android.util.FloatMath fue recomendado por razones de rendimiento al operar en flotadores.Sin embargo, en el hardware moderno dobles son tan rápidos como float (aunque toman más memoria) y en las versiones recientes de Android, FloatMath es en realidad más lento que el uso de java.lang.Math debido a la forma en que el JIT optimiza java.lang.Math. Por lo tanto, debe utilizar Math en lugar de FloatMath si sólo está dirigido a Froyo y superiores.

Espero que esto ayude.

http://developer.android.com/training/articles/perf-tips.html#AvoidFloat

Evitar el uso de puntos flotantes

Como regla general, el punto flotante es aproximadamente 2 veces más lento que el entero en los dispositivos con Android.

En términos de velocidad, no hay diferencia entre float y doble en el hardware más moderno. Espacio-sabio, el doble es 2x más grande. Al igual que ocurre con las máquinas de escritorio, suponer que el espacio no es un problema, debe preferir el doble para flotar.

Además, incluso para números enteros, algunos procesadores tienen hardware multiplicado pero carecen de división de hardware. En tales casos, la división entera y las operaciones de módulo se realizan en el software, algo en que pensar si está diseñando una tabla hash o haciendo un montón de matemáticas.

Un flotador es 32 bits o 4 bytes

Un doble es de 64 bits o 8 bytes

Así que sí, los flotadores son la mitad del tamaño de acuerdo con el libro de certificación de sol java.

En términos de velocidad, no hay diferencia entre float y doble en el hardware más moderno.

Los dispositivos muy baratos parecen tener una FPU limitada donde el flotador es más rápido que el doble. He probado en un dispositivo CMX que actualmente se comercializa como una de las tabletas más baratas del mundo:

  • El código de prueba "flotante" tarda 4,7 segundos
  • Mismo código con "doble" toma 6,6 segundos

Esta pregunta se ha hecho un par de veces …

Sí. Porque la respuesta difiere para diferentes tipos de hardware. En las computadoras de escritorio el doble tiene la misma velocidad que el flotador. En los dispositivos sin FPU (interesante para los hackers de enrutador WLAN) float es 2-5 veces más rápido que el doble; Y en dispositivos con 32-bit FPU (encontrado a menudo en aplicaciones industriales y automotoras) incluso hasta 100 veces.

Por favor, echa un vistazo a este artículo …

La última sección del artículo dice que usted tiene que hacer mediciones de tiempo en el dispositivo de hardware que va a utilizar para estar 100% seguro.

Me pregunté acerca de esto también y escribió una pequeña prueba:

#include <iostream> #include <chrono> template<typename numType> void test(void) { std::cout<< "Size of variable: " << sizeof(numType) << std::endl; numType array[20000]; auto t1 = std::chrono::high_resolution_clock::now(); // fill array for( numType& number : array ) { number = 1.0014535; } auto t2 = std::chrono::high_resolution_clock::now(); // multiply each number with itself 10.000 times for( numType& number : array ) { for( int i=0; i < 10000 ; i++ ) { number *= number; } } auto t3 = std::chrono::high_resolution_clock::now(); auto filltime = t2 - t1; auto calctime = t3 - t2; std::cout<< "Fill time: " << filltime.count() << std::endl; std::cout<< "Calc time: " << calctime.count() << std::endl; } int main(int argc, char* argv[]) { test<float>(); test<double>(); } 

He corrido y compilado en Ubuntu 12.04 x64 con GCC en un procesador Intel i7 3930k

Estos fueron los resultados:

 Size of variable: 4 Fill time: 69 Calc time: 694303 Size of variable: 8 Fill time: 76 Calc time: 693363 

Los resultados fueron reproducibles. Así que la asignación de memoria para el doble toma un poco más, pero el tiempo de cálculo real es exactamente el mismo.


Por curiosidad también corrí y lo compilé bajo Windows 7 x64 usando Visual Studio 2012 en modo de liberación en un procesador intel i7 920

(La unidad del tiempo es diferente por lo que no se comparan los resultados anteriores a estos: sólo es válido para la comparación interna)

 Size of variable: 4 Fill time: 0 Calc time: 3200183 Size of variable: 8 Fill time: 0 Calc time: 3890223 

Los resultados fueron reproducibles.

Parece que en la asignación de ventanas es instantánea, tal vez porque linux realmente no le da memoria hasta que lo use mientras que las ventanas sólo manos todo a usted a la vez, que requieren menos llamadas del sistema. O tal vez la asignación se optimiza lejos.

La multiplicación de dobles es 21,5% más lenta aquí que para los flotadores. Esta diferencia con la prueba anterior es probable debido al procesador diferente (que es mi mejor conjetura por lo menos).

La documentación de android citada indica que los números enteros son preferibles para operaciones rápidas. Esto parece un poco extraño en la cara de él, pero la velocidad de un algoritmo utilizando vs ints vs flotantes dobles depende de varias capas:

  1. El JIT o VM: estos convertirán las operaciones matemáticas en el conjunto de instrucciones nativo de la máquina host y que la traducción puede tener un gran impacto en el rendimiento. Dado que el hardware subyacente puede variar drásticamente de una plataforma a otra, puede ser muy difícil escribir una VM o JIT que emita código óptimo en todos los casos. Probablemente sea mejor utilizar el tipo rápido recomendado de JIT / VM (en este caso, enteros) porque, a medida que los JITs y VMs mejoran en la emisión de instrucciones nativas más eficientes, su código de alto nivel debería obtener los aumentos de rendimiento asociados sin ningún tipo modificación.

  2. El hardware nativo (por qué el primer nivel no es perfecto): la mayoría de los procesadores de hoy en día tienen unidades de punto flotante de hardware (los soportes de flotación y dobles). Si está presente una unidad de hardware, los flotadores / dobles pueden ser más rápidos que los enteros, a menos que también haya soporte de hardware entero. El problema es que la mayoría de las CPUs tienen algún tipo de soporte SIMD (Single Instruction Multiple Data) que permite vectorizar las operaciones si los tipos de datos son lo suficientemente pequeños (por ejemplo, agregar 4 flotadores en una instrucción poniendo dos en cada registro en lugar de tener Para usar un registro entero para cada uno de 4 dobles). Esto puede permitir que los tipos de datos que usan menos bits sean procesados ​​mucho más rápido que un doble, a expensas de la precisión.

La optimización de la velocidad requiere un conocimiento detallado de ambos niveles y de cómo interactúan. Incluso optimizar para el uso de memoria puede ser complicado porque la VM puede elegir representar sus datos en una huella más grande por otras razones: un flotador puede ocupar 8 bytes en el código de la VM, aunque es menos probable. Todo esto hace que la optimización sea casi la antítesis de la portabilidad. Así que aquí de nuevo, es mejor usar el tipo de datos "rápido" recomendado por la VM, ya que esto debería dar como resultado el mejor rendimiento promedio de los dispositivos compatibles.

Esto no es una mala pregunta en absoluto, incluso en los escritorios. Sí, son muy rápidos hoy en día, pero si están implementando un algoritmo complicado (por ejemplo, la transformada rápida de Fourier), incluso las optimizaciones pequeñas pueden tener un enorme impacto en el tiempo de ejecución del algoritmo. En cualquier caso, la respuesta a su pregunta "que es más rápido: flota o duplica" es "depende" 🙂

  • Android: ¿Hay alguna manera de acelerar canvas.drawBitmap?
  • Reserva de almacenamiento interno del dispositivo Android para futuros registros críticos de aplicaciones
  • Cargas lentas en el emulador de Android
  • ¿Cuál es la mejor alternativa para las preferencias compartidas en Android?
  • Problema de velocidad de Android con la deserialización mediante SimpleXML
  • Android: patrón de ViewHolder y diferentes tipos de filas?
  • ¿Cómo puedo eliminar los recursos no utilizados de las bibliotecas de terceros que he incluido en Android?
  • Rendimiento ORM: ¿es greenDAO más rápido que ORMLite?
  • ¿Alguna manera alrededor del funcionamiento terrible de SecretKeyFactory con LVL y AESObfuscator?
  • Timertask o manejador
  • Variables estáticas, patrón y rendimiento de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.