我读到JVM存储内部短,整数和长4个字节。我从2000年的一篇文章中读到它,所以我不知道它现在是多么真实。
对于较新的JVM,使用short over integer / long是否有任何性能提升?自2000年以来,这部分实施是否发生了变化?
由于
答案 0 :(得分:15)
整数类型存储在许多字节中,具体取决于确切的类型:
请参阅spec here。
至于表现,取决于你在做什么。 例如,如果要将字面值分配给字节或短字节,它们将被升级为int,因为默认情况下文字值被视为整数。
byte b = 10; // upscaled to int, because "10" is an int
这就是你不能做的原因:
byte b = 10;
b = b + 1; // Error, right member converted to int, cannot be reassigned to byte without a cast.
因此,如果您打算使用字节或短路来执行某些循环,那么您将无法获得任何收益。
for (byte b=0; b<10; b++)
{ ... }
另一方面,如果您使用字节或短路数组来存储某些数据,您显然会从缩小的数据中受益。
byte[] bytes = new byte[1000];
int[] ints = new int[1000]; // 4X the size
所以,我的答案是:它取决于:)
答案 1 :(得分:12)
long 64 –9,223,372,036,854,775,808 to 9 ,223,372,036,854,775,807
int 32 –2,147,483,648 to 2,147,483,647
short 16 –32,768 to 32,767
byte 8 –128 to 127
使用您需要的东西,我认为由于范围较小而很少使用短裤,并且它采用大端格式。
任何性能提升都是最小的,但就像我说的那样,如果你的应用程序需要的范围比使用int的短范围更大。长型对你来说可能太大了;但这一切都取决于你的申请。
如果您对空间有疑虑,只应使用短(内存),否则请使用int(在大多数情况下)。如果你正在创建数组,那么通过声明int和short类型的数组来尝试它。 Short将使用1/2的空间而不是int。但是如果你根据速度/性能运行测试,你会发现很少甚至没有区别(如果你正在处理数组),此外,你唯一能节省的就是空间。
也是评论员提到的很长,因为长是64位。您将无法以4个字节存储long的大小(请注意long的范围)。
答案 2 :(得分:8)
这是一个实现细节,但出于性能原因,大多数JVM仍然会为每个变量使用一个完整的单词(或更多),因为CPU以字为单位访问内存。如果JVM将变量存储在子字单元和位置中,它实际上会更慢。
这意味着32位JVM将使用4个字节(甚至是布尔值),而64位JVM将使用8个字节。但是,对于数组元素也是如此。
答案 3 :(得分:0)
我同意user2391480,计算短片似乎更昂贵。这是一个例子,在我的机器上(Java7 64位,Intel i7-3770,Windows 7),短路操作比整数和长度慢大约50倍。
public class ShortTest {
public static void main(String[] args){
calculate();
calculate();
}
public static void calculate(){
int N = 100000000;
long time1=System.currentTimeMillis();
short s=0;
for(int i = 0; i<N;i++) {
s+=1;
s-=1;
}
long time2=System.currentTimeMillis();
System.out.println("Time elapsed for shorts: "+(time2-time1));
long time3=System.currentTimeMillis();
int in=0;
for(int i = 0; i<N;i++) {
in+=1;
in-=1;
}
long time4=System.currentTimeMillis();
System.out.println("Time elapsed for ints: "+(time4-time3));
long time5=System.currentTimeMillis();
long l=0;
for(int i = 0; i<N;i++) {
l+=1;
l-=1;
}
long time6=System.currentTimeMillis();
System.out.println("Time elapsed for longs: "+(time6-time5));
System.out.println(s+in+l);
}
}
输出:
Time elapsed for shorts: 113
Time elapsed for ints: 2
Time elapsed for longs: 2
0
Time elapsed for shorts: 119
Time elapsed for ints: 2
Time elapsed for longs: 2
0
注意:指定&#34; 1&#34;做一个简短的(为了避免每次投射,正如用户Robotnik所建议的那样延迟)似乎没有帮助,例如。
short s=0;
short one = (short)1;
for(int i = 0; i<N;i++) {
s+=one;
s-=one;
}
编辑:根据评论中用户Hot Licks的请求进行修改,以便在main方法之外多次调用calculate()方法。
答案 4 :(得分:0)
基本上没有区别。一个人必须&#34;混淆&#34;有点JITC,以至于它没有认识到递增/递减操作是自我取消的,并且结果没有被使用。这样做,这三个案件大致相同。 (实际上,short
似乎要快一点。)
public class ShortTest {
public static void main(String[] args){
// Do the inner method 5 times to see how it changes as the JITC attempts to
// do further optimizations.
for (int i = 0; i < 5; i++) {
calculate(i);
}
}
public static void calculate(int passNum){
System.out.println("Pass " + passNum);
// Broke into two (nested) loop counters so the total number of iterations could
// be large enough to be seen on the clock. (Though this isn't as important when
// the JITC over-optimizations are prevented.)
int M = 100000;
int N = 100000;
java.util.Random r = new java.util.Random();
short x = (short) r.nextInt(1);
short y1 = (short) (x + 1);
int y2 = x + 1;
long y3 = x + 1;
long time1=System.currentTimeMillis();
short s=x;
for (int j = 0; j<M;j++) {
for(int i = 0; i<N;i++) {
s+=y1;
s-=1;
if (s > 100) {
System.out.println("Shouldn't be here");
}
}
}
long time2=System.currentTimeMillis();
System.out.println("Time elapsed for shorts: "+(time2-time1) + " (" + time1 + "," + time2 + ")");
long time3=System.currentTimeMillis();
int in=x;
for (int j = 0; j<M;j++) {
for(int i = 0; i<N;i++) {
in+=y2;
in-=1;
if (in > 100) {
System.out.println("Shouldn't be here");
}
}
}
long time4=System.currentTimeMillis();
System.out.println("Time elapsed for ints: "+(time4-time3) + " (" + time3 + "," + time4 + ")");
long time5=System.currentTimeMillis();
long l=x;
for (int j = 0; j<M;j++) {
for(int i = 0; i<N;i++) {
l+=y3;
l-=1;
if (l > 100) {
System.out.println("Shouldn't be here");
}
}
}
long time6=System.currentTimeMillis();
System.out.println("Time elapsed for longs: "+(time6-time5) + " (" + time5 + "," + time6 + ")");
System.out.println(s+in+l);
}
}
结果:
C:\JavaTools>java ShortTest
Pass 0
Time elapsed for shorts: 59119 (1422405830404,1422405889523)
Time elapsed for ints: 45810 (1422405889524,1422405935334)
Time elapsed for longs: 47840 (1422405935335,1422405983175)
0
Pass 1
Time elapsed for shorts: 58258 (1422405983176,1422406041434)
Time elapsed for ints: 45607 (1422406041435,1422406087042)
Time elapsed for longs: 46635 (1422406087043,1422406133678)
0
Pass 2
Time elapsed for shorts: 31822 (1422406133679,1422406165501)
Time elapsed for ints: 39663 (1422406165502,1422406205165)
Time elapsed for longs: 37232 (1422406205165,1422406242397)
0
Pass 3
Time elapsed for shorts: 30392 (1422406242398,1422406272790)
Time elapsed for ints: 37949 (1422406272791,1422406310740)
Time elapsed for longs: 37634 (1422406310741,1422406348375)
0
Pass 4
Time elapsed for shorts: 31303 (1422406348376,1422406379679)
Time elapsed for ints: 36583 (1422406379680,1422406416263)
Time elapsed for longs: 38730 (1422406416264,1422406454994)
0
C:\JavaTools>java -version
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b19)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
答案 5 :(得分:-2)
短型计算非常昂贵。
以下面的无用循环为例:
short t=0;
//int t=0;
//long t=0;
for(many many times...)
{
t+=1;
t-=1;
}
如果它是一个短片,那么它的长度比它是一个整数或者长整数的时间要长1000倍。
在Linux上检查64位JVM版本6/7