Can you help me clarify the usages of the float primitive in Java?
你能帮我澄清一下Java中float原语的用法吗?
My understanding is that converting a float value to double and vice-versa can be problematic. I read (rather long time ago and not sure that it's actual true anymore with new JVMs) that float's performance is much worse than double's. And of course floats have less precision than double.
我的理解是将浮点值转换为double,反之亦然可能会有问题。我读过(很久很久以前并且不确定新的JVM是否真的存在)浮动的性能比双重性差得多。当然浮标的精度低于双精度。
I also remember that when I worked with AWT and Swing I had some problems with using float or double (like using Point2D.Float or Point2D.Double).
我还记得当我使用AWT和Swing时,我在使用float或double时遇到了一些问题(比如使用Point2D.Float或Point2D.Double)。
So, I see only 2 advantages of float over double:
所以,我看到浮动超过双重的两个优点:
-
It needs only 4 bytes while double needs 8 bytes
它只需要4个字节,而double需要8个字节
-
The Java Memory Model (JMM) guarantees that assignment operation is atomic with float variables while it's not atomic with double's.
Java内存模型(JMM)保证赋值操作是浮点变量的原子,而不是double的原子。
Are there any other cases where float is better then double? Do you use float in your applications?
有没有其他情况下浮动比双重更好?你在应用程序中使用float吗?
5 个解决方案
#1
15
The reason for including the float type is to some extent historic: it represents a standard IEEE floating point representation from the days when shaving 4 bytes off the size of a floating point number in return for extremely poor precision was a tradeoff worth making.
包含浮点类型的原因在某种程度上是历史性的:它代表了从浮点数大小减去4个字节以来的标准IEEE浮点表示,以换取极差的精度是值得做出的权衡。
Nowadays, uses for float are pretty limited. But, for example, having the data type can make it easier to write code that needs interoperability with older systems that do use float.
如今,浮法的用途非常有限。但是,例如,拥有数据类型可以更容易地编写需要与使用float的旧系统进行互操作的代码。
As far as performance is concerned, I think the float and double are essentially identical except for the performance of divisions. Generally, whichever you use, the processor converts to its internal format, does the calculation, then converts back again, and the actual calculation effectively takes a fixed time. In the case of divisions, on Intel processors at least, as I recall the time taken to do a division is generally one clock cycle per 2 bits of precision, so that whether you use float or double does make a difference.
就性能而言,我认为浮点和双精度基本相同,除了划分的性能。通常,无论您使用哪种,处理器都会转换为其内部格式,进行计算,然后再转换回来,实际计算有效地需要一段固定的时间。在划分的情况下,至少在Intel处理器上,我记得进行除法所花费的时间通常是每2位精度一个时钟周期,因此无论你使用float还是double,都会产生影响。
Unless you really really have a strong reason for using it, in new code, I would generally avoid 'float'.
除非你真的有充分的理由使用它,否则在新代码中,我通常会避免'浮动'。
#2
7
Those two reasons you just gave are huge.
你刚才给出的两个原因是巨大的。
If you have a 3D volume that's 1k by 1k by 64, and then have many timepoints of that data, and then want to make a movie of maximum intensity projections, the fact that float is half the size of double could be the difference between finishing quickly and thrashing because you ran out of memory.
如果你的3D体积是1k乘1k乘64,然后有很多时间点的数据,然后想制作一个最大强度投影的电影,浮动的一半大小的事实可能是完成之间的差异因为你的记忆力不足而快速而痉挛。
Atomicity is also huge, from a threading standpoint.
从线程的角度来看,原子性也是巨大的。
There's always going to be a tradeoff between speed/performance and accuracy. If you have a number that's smaller than 2^31 and an integer, then an integer is always a better representation of that number than a float, just because of the precision loss. You'll have to evaluate your needs and use the appropriate types for your problems.
在速度/性能和准确性之间总会有一个权衡。如果你的数字小于2 ^ 31且是一个整数,那么整数总是比浮点数更好地表示该数字,只是因为精度损失。您必须评估您的需求并针对您的问题使用适当的类型。
#3
3
I think you nailed it when you mention storage, with floats being half the size.
当你提到存储时,我认为你钉了它,浮动的大小是它的一半。
Using floats may show improved performance over doubles for applications processing large arrays of floating point numbers such that memory bandwith is the limiting factor. By switching to float[]
from double[]
and halving the data size, you effectively double the throughput, because twice as many values can be fetched in a given time. Although the cpu has a little more work to do converting the float to a double, this happens in parallel with the memory fetch, with the fetch taking longer.
对于处理大型浮点数阵列的应用程序而言,使用浮点数可能会显示出比双精度更高的性能,因此内存带宽是限制因素。通过从double []切换到float []并将数据大小减半,可以有效地使吞吐量加倍,因为在给定时间内可以获取两倍的值。尽管cpu在将float转换为double方面还有一些工作要做,但这与内存提取同时发生,并且获取时间更长。
For some applications the loss of precision might be worth trading for the gain in performance. Then again... :-)
对于某些应用,精度损失可能值得交易以获得性能提升。然后...... :-)
#4
2
It is true that doubles might in some cases have faster operations than floats. However, this requires that everything fits in the L1-cache. With floats you can have twice as much in a cache-line. This can make some programs run almost twice as fast.
确实,在某些情况下,双打可能比浮点数更快。但是,这要求所有内容都适合L1缓存。使用浮动,您可以在缓存行中使用两倍。这可以使一些程序的运行速度几乎快两倍。
SSE instructions can also work with 4 floats in parallel instead of 2, but I doubt that the JIT actually uses those. I might be wrong though.
SSE指令也可以并行使用4个浮点数而不是2个浮点数,但我怀疑JIT实际上是使用它们。我可能错了。
#5
2
So yes, advantages of floats:
所以是的,浮动的优点:
- Only requires 4 bytes
- 只需要4个字节
- Atomic assignment
- 原子分配
- Arithmetic should be faster, especially on 32bit architectures, since there are specific float byte codes.
- 算术应该更快,特别是在32位架构上,因为有特定的浮点字节码。
Ways to mitigate these when using doubles:
使用双打时减轻这些的方法:
- Buy more RAM, it's really cheap.
- 买更多的RAM,它真的很便宜。
- Use volatile doubles if you need atomic assignment.
- 如果需要原子分配,请使用volatile double。
- Do tests, verify the performance of each, if one really is faster there isn't a lot you can do about it.
- 做测试,验证每个的性能,如果一个真的更快,你可以做很多事情。
Someone else mentioned that this is similar to the short vs int argument, but it is not. All integer types (including boolean) except long are stored as 4 byte integers in the Java memory model unless stored in an array.
有人提到这类似于short vs int参数,但事实并非如此。除long存储在数组中之外,除了long之外的所有整数类型(包括boolean)都存储为Java内存模型中的4字节整数。
#1
15
The reason for including the float type is to some extent historic: it represents a standard IEEE floating point representation from the days when shaving 4 bytes off the size of a floating point number in return for extremely poor precision was a tradeoff worth making.
包含浮点类型的原因在某种程度上是历史性的:它代表了从浮点数大小减去4个字节以来的标准IEEE浮点表示,以换取极差的精度是值得做出的权衡。
Nowadays, uses for float are pretty limited. But, for example, having the data type can make it easier to write code that needs interoperability with older systems that do use float.
如今,浮法的用途非常有限。但是,例如,拥有数据类型可以更容易地编写需要与使用float的旧系统进行互操作的代码。
As far as performance is concerned, I think the float and double are essentially identical except for the performance of divisions. Generally, whichever you use, the processor converts to its internal format, does the calculation, then converts back again, and the actual calculation effectively takes a fixed time. In the case of divisions, on Intel processors at least, as I recall the time taken to do a division is generally one clock cycle per 2 bits of precision, so that whether you use float or double does make a difference.
就性能而言,我认为浮点和双精度基本相同,除了划分的性能。通常,无论您使用哪种,处理器都会转换为其内部格式,进行计算,然后再转换回来,实际计算有效地需要一段固定的时间。在划分的情况下,至少在Intel处理器上,我记得进行除法所花费的时间通常是每2位精度一个时钟周期,因此无论你使用float还是double,都会产生影响。
Unless you really really have a strong reason for using it, in new code, I would generally avoid 'float'.
除非你真的有充分的理由使用它,否则在新代码中,我通常会避免'浮动'。
#2
7
Those two reasons you just gave are huge.
你刚才给出的两个原因是巨大的。
If you have a 3D volume that's 1k by 1k by 64, and then have many timepoints of that data, and then want to make a movie of maximum intensity projections, the fact that float is half the size of double could be the difference between finishing quickly and thrashing because you ran out of memory.
如果你的3D体积是1k乘1k乘64,然后有很多时间点的数据,然后想制作一个最大强度投影的电影,浮动的一半大小的事实可能是完成之间的差异因为你的记忆力不足而快速而痉挛。
Atomicity is also huge, from a threading standpoint.
从线程的角度来看,原子性也是巨大的。
There's always going to be a tradeoff between speed/performance and accuracy. If you have a number that's smaller than 2^31 and an integer, then an integer is always a better representation of that number than a float, just because of the precision loss. You'll have to evaluate your needs and use the appropriate types for your problems.
在速度/性能和准确性之间总会有一个权衡。如果你的数字小于2 ^ 31且是一个整数,那么整数总是比浮点数更好地表示该数字,只是因为精度损失。您必须评估您的需求并针对您的问题使用适当的类型。
#3
3
I think you nailed it when you mention storage, with floats being half the size.
当你提到存储时,我认为你钉了它,浮动的大小是它的一半。
Using floats may show improved performance over doubles for applications processing large arrays of floating point numbers such that memory bandwith is the limiting factor. By switching to float[]
from double[]
and halving the data size, you effectively double the throughput, because twice as many values can be fetched in a given time. Although the cpu has a little more work to do converting the float to a double, this happens in parallel with the memory fetch, with the fetch taking longer.
对于处理大型浮点数阵列的应用程序而言,使用浮点数可能会显示出比双精度更高的性能,因此内存带宽是限制因素。通过从double []切换到float []并将数据大小减半,可以有效地使吞吐量加倍,因为在给定时间内可以获取两倍的值。尽管cpu在将float转换为double方面还有一些工作要做,但这与内存提取同时发生,并且获取时间更长。
For some applications the loss of precision might be worth trading for the gain in performance. Then again... :-)
对于某些应用,精度损失可能值得交易以获得性能提升。然后...... :-)
#4
2
It is true that doubles might in some cases have faster operations than floats. However, this requires that everything fits in the L1-cache. With floats you can have twice as much in a cache-line. This can make some programs run almost twice as fast.
确实,在某些情况下,双打可能比浮点数更快。但是,这要求所有内容都适合L1缓存。使用浮动,您可以在缓存行中使用两倍。这可以使一些程序的运行速度几乎快两倍。
SSE instructions can also work with 4 floats in parallel instead of 2, but I doubt that the JIT actually uses those. I might be wrong though.
SSE指令也可以并行使用4个浮点数而不是2个浮点数,但我怀疑JIT实际上是使用它们。我可能错了。
#5
2
So yes, advantages of floats:
所以是的,浮动的优点:
- Only requires 4 bytes
- 只需要4个字节
- Atomic assignment
- 原子分配
- Arithmetic should be faster, especially on 32bit architectures, since there are specific float byte codes.
- 算术应该更快,特别是在32位架构上,因为有特定的浮点字节码。
Ways to mitigate these when using doubles:
使用双打时减轻这些的方法:
- Buy more RAM, it's really cheap.
- 买更多的RAM,它真的很便宜。
- Use volatile doubles if you need atomic assignment.
- 如果需要原子分配,请使用volatile double。
- Do tests, verify the performance of each, if one really is faster there isn't a lot you can do about it.
- 做测试,验证每个的性能,如果一个真的更快,你可以做很多事情。
Someone else mentioned that this is similar to the short vs int argument, but it is not. All integer types (including boolean) except long are stored as 4 byte integers in the Java memory model unless stored in an array.
有人提到这类似于short vs int参数,但事实并非如此。除long存储在数组中之外,除了long之外的所有整数类型(包括boolean)都存储为Java内存模型中的4字节整数。