有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java短、整数、长性能

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

对于较新的JVM,使用short-over-integer/long是否会提高性能?自2000年以来,这部分实施是否发生了变化

谢谢


共 (6) 个答案

  1. # 1 楼答案

    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的short go的范围,那么long类型对您来说可能太大了;但这一切都取决于你的应用程序

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

    也就是说注释者提到了long,因为long是64位的。您将无法在4字节内存储long的大小(请注意long的范围)

  2. # 2 楼答案

    基本上没有区别。我们必须稍微“混淆”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)
    
  3. # 3 楼答案

    我同意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
    

    注意:将“1”指定为短(为了避免每次施放,正如用户Robotnik建议的延迟源)似乎没有帮助,例如

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

    编辑:根据用户在注释中热点击的请求进行修改,以便在主方法之外多次调用calculate()方法

  4. # 4 楼答案

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

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

  5. # 5 楼答案

    短类型的计算非常昂贵

    以以下无用循环为例:

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

    如果它是一个短字符,它将比int或long长1000倍

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

  6. # 6 楼答案

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

    • 8位字节
    • 短于16位,有符号
    • 32位整数,有符号
    • 长64位,有符号

    spec here

    至于性能,这取决于你用它们做什么。 例如,如果要将文字值分配给字节或短字符,它们将被放大为int,因为文字值在默认情况下被视为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
    

    因此,我的答案是:视情况而定:)