2010-04-28 14 views
20

¿Me puede ayudar a aclarar los usos de la primitiva float en Java?¿Con qué propósito Java tiene un tipo primitivo flotante?

Mi comprensión es que la conversión de un valor de flotación a doble y viceversa puede ser problemático. Leí (hace bastante tiempo y no estoy seguro de que ya sea verdad con las nuevas JVM) que el rendimiento de Float es mucho peor que el doble. Y, por supuesto, los flotadores tienen menos precisión que el doble.

También recuerdo que cuando trabajé con AWT y Swing tuve algunos problemas con el uso de flotación o doble (como usar Point2D.Float o Point2D.Double).

Por lo tanto, veo sólo 2 ventajas de flotación más del doble:

  1. Se necesita sólo 4 bytes mientras que las necesidades dobles 8 bytes

  2. el modelo de memoria de Java (JMM) garantiza que la operación de asignación es atómico con variables flotantes mientras que no es atómico con dobles.

¿Hay algún otro caso en el que el flotador sea mejor que el doble? ¿Usas flotador en tus aplicaciones?

+4

"Me parece que la única razón valiosa por la que java ha flotado es la compatibilidad con versiones anteriores". Usted dice esto cuando ha enumerado previamente dos ventajas de 'float' ... –

+1

* Demagogy? * Tal vez podría haberlo dicho mejor (" ¿Cuándo usar 'float' en lugar de' double'? "), Pero * demagogy? * – egrunin

+0

¿Qué ventaja tiene short sobre int si int tiene un rango mayor? La respuesta es la misma aquí. – Malcolm

Respuesta

15

La razón para incluir el tipo de flotador es hasta cierto punto histórica: representa una representación de punto flotante IEEE estándar de los días cuando se afeita 4 bytes del tamaño de un número de punto flotante a cambio para una precisión extremadamente pobre, valía la pena sacrificarse.

Hoy en día, los usos para flotar son bastante limitados. Pero, por ejemplo, tener el tipo de datos puede hacer que sea más fácil escribir código que necesita interoperabilidad con sistemas más antiguos que usan flotador.

En lo que respecta al rendimiento, creo que el flotador y el doble son esencialmente idénticos excepto por el rendimiento de las divisiones. En general, cualquiera que sea su uso, el procesador convierte a su formato interno, hace el cálculo, luego vuelve a convertir, y el cálculo real efectivamente toma un tiempo fijo. En el caso de las divisiones, al menos en los procesadores Intel, como recuerdo, el tiempo necesario para hacer una división generalmente es de un ciclo de reloj por cada 2 bits de precisión, por lo que si usa flotación o doble sí hace la diferencia.

A menos que realmente tenga una buena razón para usarlo, en un código nuevo, generalmente evitaría "flotar".

+2

Vale la pena señalar que en las CPU Intel, la representación interna es de 80 bits, que es diferente de * both * 32-bit 'float' y 64-bit' double'. Entonces, una conversión ocurre en cualquier caso. –

+1

Sí, absolutamente ... lo siento, pensé que estaba claro cuando dije "lo que sea que use [...] convierte a su formato interno". Pero sí, completamente de acuerdo. –

+2

Y la existencia de MP3 es hasta cierto punto histórica: proviene de los días en que vale la pena afeitarse 50-90% del tamaño de sus archivos de audio a cambio de una precisión reducida. ** ¡En serio! ** Deja de pensar 4 bytes y comienza a pensar en el 50%. Si tiene miles de horas de audio de punto flotante, 32 bits es una precisión suficiente, y duplicar el tamaño de almacenamiento para una precisión adicional sería inútil. ¡Piensa en matrices, no en variables individuales! –

7

Esas dos razones que acaba de dar son enormes.

Si tiene un volumen 3D de 1k por 1k por 64, y luego tiene muchos puntos de tiempo de esos datos, y luego quiere hacer una película de proyecciones de máxima intensidad, el hecho de que el flotador sea la mitad del doble podría ser la diferencia entre terminar rápido y golpear porque se te acabó la memoria.

La atomicidad también es enorme, desde el punto de vista de la rosca.

Siempre habrá una compensación entre velocidad/rendimiento y precisión. Si tiene un número que es menor que 2^31 y un número entero, entonces un entero siempre es una mejor representación de ese número que un flotador, solo por la pérdida de precisión. Deberá evaluar sus necesidades y utilizar los tipos adecuados para sus problemas.

2

Así que sí, ventajas de flotadores:

  1. sólo requiere 4 bytes
  2. asignación Atómica
  3. aritmética debe ser más rápido, especialmente en arquitecturas de 32 bits, ya que hay códigos de bytes específicos de flotación.

maneras de mitigar estos cuando se utiliza en dobles:

  1. compra más memoria RAM, es muy barato.
  2. Usa dobles volátiles si necesitas asignación atómica.
  3. Realice las pruebas, verifique el rendimiento de cada una; si realmente es más rápido, no hay mucho que pueda hacer al respecto.

Alguien más mencionó que esto es similar al argumento short vs int, pero no lo es. Todos los tipos enteros (incluido booleano), excepto long, se almacenan como enteros de 4 bytes en el modelo de memoria Java a menos que estén almacenados en una matriz.

+1

Como campos, los tipos integrales toman 4 bytes, pero no cuando se almacenan como matrices. P.ej. un corto [] toma 2 bytes por índice. – mdma

+0

Sí, bastante correcto. (Excepto de largo, que en realidad está almacenado en dos ranuras). – Geoff

3

Creo que lo encasilló cuando mencionó el almacenamiento, con flotadores de la mitad del tamaño.

El uso de flotadores puede mostrar un rendimiento mejorado en comparación con los dobles para aplicaciones que procesan grandes matrices de números de punto flotante de modo que el ancho de banda de memoria es el factor limitante. Al cambiar a float[] desde double[] y reducir a la mitad el tamaño de los datos, efectivamente duplica el rendimiento, ya que se pueden obtener el doble de valores en un momento dado. Aunque la CPU tiene un poco más de trabajo para convertir el flotador en un doble, esto sucede en paralelo con la recuperación de la memoria, con la recuperación tardando más.

Para algunas aplicaciones, la pérdida de precisión puede valer la pena negociar por la ganancia en el rendimiento. Entonces otra vez ... :-)

2

Es cierto que los dobles pueden en algunos casos tener operaciones más rápidas que los flotadores. Sin embargo, esto requiere que todo encaje en el caché L1. Con flotadores puede tener el doble en una línea de caché. Esto puede hacer que algunos programas se ejecuten casi el doble de rápido.

Las instrucciones de SSE también pueden funcionar con 4 flotadores en paralelo en lugar de 2, pero dudo que el JIT realmente los use. Sin embargo, podría estar equivocado.

Cuestiones relacionadas