在java中,使用byte或short而不是int和float而不是double更有效吗?
我注意到我总是使用 int 和 doubles,无论数字需要多大或多小.那么在java中,使用byte
或short
代替int
和float
代替双
?
I've noticed I've always used int and doubles no matter how small or big the number needs to be. So in java, is it more efficient to use byte
or short
instead of int
and float
instead of double
?
所以假设我有一个包含大量整数和双精度数的程序.如果我知道这个数字合适,是否值得将我的整数更改为字节或短裤?
So assume I have a program with plenty of ints and doubles. Would it be worth going through and changing my ints to bytes or shorts if I knew the number would fit?
我知道 java 没有无符号类型,但如果我知道这个数字只是正数,我还能做些什么吗?
I know java doesn't have unsigned types but is there anything extra I could do if I knew the number would be positive only?
我所说的高效主要是指处理.我假设如果所有变量都是一半大小,那么垃圾收集器会快得多,并且计算也可能会更快一些.(我想因为我正在使用 android,所以我也需要有点担心 ram)
By efficient I mostly mean processing. I'd assume the garbage collector would be a lot faster if all the variables would be half size and that calculations would probably be somewhat faster too. ( I guess since I am working on android I need to somewhat worry about ram too)
(我假设垃圾收集器只处理对象而不是原始对象,但仍会删除废弃对象中的所有原始对象,对吧?)
(I'd assume the garbage collector only deals with Objects and not primitive but still deletes all the primitives in abandoned objects right? )
我用我拥有的一个小型 android 应用程序进行了尝试,但并没有真正注意到有什么不同.(虽然我没有科学地"测量任何东西.)
I tried it with a small android app I have but didn't really notice a difference at all. (Though I didn't "scientifically" measure anything.)
我认为它应该更快更高效是不是错了?我不想经历并改变一个庞大的程序中的所有内容,以发现我浪费了我的时间.
Am I wrong in assuming it should be faster and more efficient? I'd hate to go through and change everything in a massive program to find out I wasted my time.
当我开始一个新项目时,是否值得从头开始?(我的意思是我认为每一点都会有所帮助,但如果是这样的话,为什么似乎没有人这样做.)
Would it be worth doing from the beginning when I start a new project? (I mean I think every little bit would help but then again if so, why doesn't it seem like anyone does it.)
推荐答案
我认为它应该更快更高效是不是错了?我不想经历并改变一个庞大的程序中的所有内容,以发现我浪费了我的时间.
Am I wrong in assuming it should be faster and more efficient? I'd hate to go through and change everything in a massive program to find out I wasted my time.
简答
是的,你错了.在大多数情况下,它在使用的空间方面差别不大.
不值得尝试优化...除非您有明确的证据表明需要优化.如果您确实需要特别优化对象字段的内存使用,您可能需要采取其他(更有效的)措施.
It is not worth trying to optimize this ... unless you have clear evidence that optimization is needed. And if you do need to optimize memory usage of object fields in particular, you will probably need to take other (more effective) measures.
Java 虚拟机使用偏移量(实际上)是 32 位原始单元大小的倍数来模拟堆栈和对象字段.因此,当您将局部变量或对象字段声明为(例如)byte
时,变量/字段将存储在 32 位单元格中,就像 int
一样.
The Java Virtual Machine models stacks and object fields using offsets that are (in effect) multiples of a 32 bit primitive cell size. So when you declare a local variable or object field as (say) a byte
, the variable / field will be stored in a 32 bit cell, just like an int
.
这有两个例外:
long
和double
值需要 2 个原始 32 位单元- 原始类型数组以打包形式表示,因此(例如)字节数组每个 32 位字包含 4 个字节.
long
anddouble
values require 2 primitive 32-bit cells- arrays of primitive types are represent in packed form, so that (for example) an array of bytes hold 4 bytes per 32bit word.
因此 可能 值得优化 long
和 double
...以及大型基元数组的使用.但一般不会.
So it might be worth optimizing use of long
and double
... and large arrays of primitives. But in general no.
理论上,JIT 可能能够优化这一点,但实际上我从未听说过有这样的 JIT.一个障碍是 JIT 通常在创建正在编译的类的实例之后才能运行.如果 JIT 优化了内存布局,您可以拥有两个(或更多)风味".同一类的对象......这将带来巨大的困难.
In theory, a JIT might be able to optimize this, but in practice I've never heard of a JIT that does. One impediment is that the JIT typically cannot run until after there instances of the class being compiled have been created. If the JIT optimized the memory layout, you could have two (or more) "flavors" of object of the same class ... and that would present huge difficulties.
查看@meriton 答案中的基准测试结果,似乎使用 short
和 byte
而不是 int
会导致乘法性能下降.事实上,如果你孤立地考虑这些操作,惩罚是巨大的.(你不应该孤立地考虑它们......但这是另一个话题.)
Looking at the benchmark results in @meriton's answer, it appears that using short
and byte
instead of int
incurs a performance penalty for multiplication. Indeed, if you consider the operations in isolation, the penalty is significant. (You shouldn't consider them in isolation ... but that's another topic.)
我认为解释是 JIT 可能在每种情况下都使用 32 位乘法指令进行乘法运算.但在 byte
和 short
的情况下,它执行 extra 指令将中间 32 位值转换为 byte
或 short
在每个循环迭代中.(理论上,这种转换可以在循环结束时完成一次......但我怀疑优化器是否能够解决这个问题.)
I think the explanation is that JIT is probably doing the multiplications using 32bit multiply instructions in each case. But in the byte
and short
case, it executes extra instructions to convert the intermediate 32 bit value to a byte
or short
in each loop iteration. (In theory, that conversion could be done once at the end of the loop ... but I doubt that the optimizer would be able to figure that out.)
无论如何,这确实指向另一个问题,即切换到 short
和 byte
作为优化.它可能会使性能更差 ...在算术和计算密集型算法中.
Anyway, this does point to another problem with switching to short
and byte
as an optimization. It could make performance worse ... in an algorithm that is arithmetic and compute intensive.
我知道 java 没有无符号类型,但如果我知道这个数字只是正数,我还能做些什么吗?
I know java doesn't have unsigned types but is there anything extra I could do if I knew the number would be positive only?
没有.无论如何,不是在性能方面.(在 Integer
、Long
等中有一些方法可以将 int
、long
等作为无符号处理.但这些并没有带来任何性能优势.这不是他们的目的.)
No. Not in terms of performance anyway. (There are some methods in Integer
, Long
, etc for dealing with int
, long
, etc as unsigned. But these don't give any performance advantage. That is not their purpose.)
(我假设垃圾收集器只处理对象而不是原始对象,但仍会删除废弃对象中的所有原始对象,对吧?)
(I'd assume the garbage collector only deals with Objects and not primitive but still deletes all the primitives in abandoned objects right? )
正确.对象的字段是对象的一部分.当对象被垃圾收集时,它就会消失.同样,当收集阵列时,阵列的单元格就会消失.当字段或单元格类型是原始类型时,值将存储在字段/单元格中......它是对象/数组的一部分......并且已被删除.
Correct. A field of an object is part of the object. It goes away when the object is garbage collected. Likewise the cells of an array go away when the array is collected. When the field or cell type is a primitive type, then the value is stored in the field / cell ... which is part of the object / array ... and that has been deleted.
相关文章