問題描述
我注意到我總是使用 int 和 doubles,無論數(shù)字需要多大或多小.那么在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
?
所以假設(shè)我有一個(gè)包含大量整數(shù)和雙精度數(shù)的程序.如果我知道這個(gè)數(shù)字合適,是否值得將我的整數(shù)更改為字節(jié)或短褲?
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 沒有無符號(hào)類型,但如果我知道這個(gè)數(shù)字只是正數(shù),我還能做些什么嗎?
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?
我所說的高效主要是指處理.我假設(shè)如果所有變量都是一半大小,那么垃圾收集器會(huì)快得多,并且計(jì)算也可能會(huì)更快一些.(我想因?yàn)槲艺谑褂?android,所以我也需要有點(diǎn)擔(dān)心 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)
(我假設(shè)垃圾收集器只處理對(duì)象而不是原始對(duì)象,但仍會(huì)刪除廢棄對(duì)象中的所有原始對(duì)象,對(duì)吧?)
(I'd assume the garbage collector only deals with Objects and not primitive but still deletes all the primitives in abandoned objects right? )
我用我擁有的一個(gè)小型 android 應(yīng)用程序進(jìn)行了嘗試,但并沒有真正注意到有什么不同.(雖然我沒有科學(xué)地"測(cè)量任何東西.)
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.)
我認(rèn)為它應(yīng)該更快更高效是不是錯(cuò)了?我不想經(jīng)歷并改變一個(gè)龐大的程序中的所有內(nèi)容,以發(fā)現(xiàn)我浪費(fèi)了我的時(shí)間.
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.
當(dāng)我開始一個(gè)新項(xiàng)目時(shí),是否值得從頭開始?(我的意思是我認(rèn)為每一點(diǎn)都會(huì)有所幫助,但如果是這樣的話,為什么似乎沒有人這樣做.)
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.)
推薦答案
我認(rèn)為它應(yīng)該更快更高效是不是錯(cuò)了?我不想經(jīng)歷并改變一個(gè)龐大的程序中的所有內(nèi)容,以發(fā)現(xiàn)我浪費(fèi)了我的時(shí)間.
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.
簡(jiǎn)答
是的,你錯(cuò)了.在大多數(shù)情況下,它在使用的空間方面差別不大.
不值得嘗試優(yōu)化...除非您有明確的證據(jù)表明需要優(yōu)化.如果您確實(shí)需要特別優(yōu)化對(duì)象字段的內(nèi)存使用,您可能需要采取其他(更有效的)措施.
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 虛擬機(jī)使用偏移量(實(shí)際上)是 32 位原始單元大小的倍數(shù)來模擬堆棧和對(duì)象字段.因此,當(dāng)您將局部變量或?qū)ο笞侄温暶鳛?例如)byte
時(shí),變量/字段將存儲(chǔ)在 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
.
這有兩個(gè)例外:
long
和double
值需要 2 個(gè)原始 32 位單元- 原始類型數(shù)組以打包形式表示,因此(例如)字節(jié)數(shù)組每個(gè) 32 位字包含 4 個(gè)字節(jié).
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.
因此 可能 值得優(yōu)化 long
和 double
...以及大型基元數(shù)組的使用.但一般不會(huì).
So it might be worth optimizing use of long
and double
... and large arrays of primitives. But in general no.
理論上,JIT 可能能夠優(yōu)化這一點(diǎn),但實(shí)際上我從未聽說過有這樣的 JIT.一個(gè)障礙是 JIT 通常在創(chuàng)建正在編譯的類的實(shí)例之后才能運(yùn)行.如果 JIT 優(yōu)化了內(nèi)存布局,您可以擁有兩個(gè)(或更多)風(fēng)味".同一類的對(duì)象......這將帶來巨大的困難.
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 答案中的基準(zhǔn)測(cè)試結(jié)果,似乎使用 short
和 byte
而不是 int
會(huì)導(dǎo)致乘法性能下降.事實(shí)上,如果你孤立地考慮這些操作,懲罰是巨大的.(你不應(yīng)該孤立地考慮它們......但這是另一個(gè)話題.)
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.)
我認(rèn)為解釋是 JIT 可能在每種情況下都使用 32 位乘法指令進(jìn)行乘法運(yùn)算.但在 byte
和 short
的情況下,它執(zhí)行 extra 指令將中間 32 位值轉(zhuǎn)換為 byte
或 short
在每個(gè)循環(huán)迭代中.(理論上,這種轉(zhuǎn)換可以在循環(huán)結(jié)束時(shí)完成一次......但我懷疑優(yōu)化器是否能夠解決這個(gè)問題.)
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.)
無論如何,這確實(shí)指向另一個(gè)問題,即切換到 short
和 byte
作為優(yōu)化.它可能會(huì)使性能更差 ...在算術(shù)和計(jì)算密集型算法中.
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 沒有無符號(hào)類型,但如果我知道這個(gè)數(shù)字只是正數(shù),我還能做些什么嗎?
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
等作為無符號(hào)處理.但這些并沒有帶來任何性能優(yōu)勢(shì).這不是他們的目的.)
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.)
(我假設(shè)垃圾收集器只處理對(duì)象而不是原始對(duì)象,但仍會(huì)刪除廢棄對(duì)象中的所有原始對(duì)象,對(duì)吧?)
(I'd assume the garbage collector only deals with Objects and not primitive but still deletes all the primitives in abandoned objects right? )
正確.對(duì)象的字段是對(duì)象的一部分.當(dāng)對(duì)象被垃圾收集時(shí),它就會(huì)消失.同樣,當(dāng)收集陣列時(shí),陣列的單元格就會(huì)消失.當(dāng)字段或單元格類型是原始類型時(shí),值將存儲(chǔ)在字段/單元格中......它是對(duì)象/數(shù)組的一部分......并且已被刪除.
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.
這篇關(guān)于在java中,使用byte或short而不是int和float而不是double更有效嗎?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!