13

我读到 JVM 在内部存储了 4 个字节的短整数和长整数。我是从 2000 年的一篇文章中读到的,所以我不知道它现在的真实性如何。

对于较新的 JVM,使用短整数/长整数是否有任何性能提升?自 2000 年以来,这部分实施是否发生了变化?

谢谢

4

6 回答 6

15

整数类型存储在许多字节中,具体取决于确切的类型:

  • 8 位字节
  • 16 位短,有符号
  • int 32 位,有符号
  • 长 64 位,有符号

请参阅此处的规范

至于性能,这取决于你用它们做什么。例如,如果您将文字值分配给字节或短整数,它们将被放大为 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

所以,我的回答是:这取决于:)

于 2010-03-04T16:11:49.467 回答
13
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 短的范围要大。long 类型可能对你来说太大了;但这一切都取决于您的应用程序。

仅当您担心空间(内存)时才应使用 short ,否则应使用 int (在大多数情况下)。如果您正在创建数组等,请通过声明 int 和 short 类型的数组来尝试。Short 将使用 1/2 的空间,而不是 int。但是,如果您根据速度/性能运行测试,您会发现几乎没有差异(如果您正在处理数组),此外,您唯一节省的就是空间。

也是评论员提到 long 因为 long 是 64 位。您将无法以 4 个字节存储 long 的大小(注意 long 的范围)。

于 2010-03-04T16:07:56.227 回答
8

这是一个实现细节,但出于性能原因,大多数 JVM 仍然会为每个变量使用一个完整的字(或更多),因为 CPU 以字为单位访问内存,这仍然是事实。如果 JVM 将变量存储在子字单元和位置中,它实际上会更慢。

这意味着 32 位 JVM 将使用 4 个短字节(甚至是布尔值),而 64 位 JVM 将使用 8 个字节。但是,数组元素并非如此。

于 2010-03-04T16:15:52.203 回答
1

基本没有区别。必须稍微“混淆” 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)
于 2015-01-28T00:57:02.163 回答
0

我同意 user2391480,用短裤计算似乎要贵得多。这是一个示例,在我的机器(Java7 64bit,Intel i7-3770,Windows 7)上,short 操作比整数和 long 慢约 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

注意:将“1”指定为短(为了避免每次都进行转换,正如用户 Robotnik 建议的那样作为延迟的来源)似乎没有帮助,例如

    short s=0;
    short one = (short)1;
    for(int i = 0; i<N;i++) {
      s+=one;
      s-=one;
    }

编辑:根据评论中用户 Hot Licks 的请求进行修改,以便在 main 方法之外多次调用 calculate() 方法。

于 2015-01-27T22:07:52.807 回答
-2

短类型的计算非常昂贵。

以下面的无用循环为例:

short t=0;
//int t=0;
//long t=0;
for(many many times...)
{
  t+=1;
  t-=1;
}

如果它是一个短的,它实际上将比它是一个 int 或一个长的时间长 1000 倍。

在 Linux 上检查 64 位 JVM 版本 6/7

于 2013-11-05T18:30:13.987 回答