我注意到我总是使用 int 和 double,无论数字需要多小或多大。 So in java, is it more efficient to use byte
or short
instead of int
and float
instead of double
?
所以假设我有一个包含大量整数和双精度数的程序。如果我知道数字合适,是否值得通过并将我的整数更改为字节或短裤?
我知道 java 没有无符号类型,但是如果我知道这个数字只会是正数,我还能做些什么吗?
我所说的高效主要是指处理。我假设如果所有变量都是一半大小,垃圾收集器会快很多,而且计算也可能会快一些。 (我想因为我在 android 上工作,所以我也需要有点担心 ram)
(我假设垃圾收集器只处理对象而不是原始对象,但仍然会删除废弃对象中的所有原始对象,对吗?)
我用我拥有的一个小型 Android 应用程序进行了尝试,但并没有真正注意到有什么不同。 (虽然我没有“科学地”测量任何东西。)
我假设它应该更快、更高效是错误的吗?我不想通过并更改大型程序中的所有内容,然后发现我浪费了时间。
当我开始一个新项目时,从一开始就值得吗? (我的意思是,我认为每一点点滴滴都会有所帮助,但话又说回来,为什么似乎没有人这样做。)
原文由 DisibioAaron 发布,翻译遵循 CC BY-SA 4.0 许可协议
简答
是的,你错了。在大多数情况下,它在所用空间方面 _几乎没有区别_。
尝试对此进行优化是 不值得 的……除非您有明确的证据表明需要进行优化。如果您确实 需要 特别优化对象字段的内存使用,您可能需要采取其他(更有效的)措施。
更长的答案
Java 虚拟机使用(实际上)32 位原始单元格大小的倍数的偏移量对堆栈和对象字段进行建模。因此,当您将局部变量或对象字段声明为(比如)a
byte
时,变量/字段将存储在 32 位单元格中,就像int
一样。有两个例外:
long
和double
值需要 2 个原始 32 位单元格因此, 可能 值得优化使用
long
和double
… 以及大型基元数组。但总的来说没有。理论上,JIT 可能 能够对此进行优化,但在实践中,我从未听说过 JIT 可以做到这一点。一个障碍是 JIT 通常只有在创建了正在编译的类的实例之后才能运行。如果 JIT 优化了内存布局,您可能会拥有同一类对象的两种(或更多)“风味”……这将带来巨大的困难。
重访
查看@meriton 的答案中的基准测试结果,似乎使用
short
和byte
而不是int
惩罚。事实上,如果您孤立地考虑这些操作,那么损失是巨大的。 (你不应该孤立地考虑它们……但那是另一个话题。)我认为解释是 JIT 可能在每种情况下都使用 32 位乘法指令进行乘法运算。 But in the
byte
andshort
case, it executes extra instructions to convert the intermediate 32 bit value to abyte
orshort
in each循环迭代。 (理论上,这种转换可以在循环结束时完成一次……但我怀疑优化器是否能够解决这个问题。)无论如何,这确实指向另一个问题,即切换到
short
和byte
作为优化。它可能会使性能 变差……在算术和计算密集型算法中。次要问题
不,无论如何不是在性能方面。 (There are some methods in
Integer
,Long
, etc for dealing withint
,long
, etc as unsigned. But these don’ t 提供任何性能优势。那不是他们的目的。)正确的。对象的字段是对象的 _一部分_。当对象被垃圾回收时,它就会消失。同样,当数组被收集时,数组的单元格也会消失。当字段或单元格类型是原始类型时,该值存储在字段/单元格中……它是对象/数组的一部分……并且已被删除。