• 三种方式交换两数值


    交换两个数的值有三种方式:

    • 使用临时变量‘寄存’
    • 不使用临时变量,原地加减:缺点是可能存在溢出
    • 使用异或
    int x = 100;
    int y = 200;
    
    //方式1:临时变量
    int z= x;
    x = y;
    y =z;
    
    //方式2:不用临时变量
    x = x+y;
    y = x-y;
    x = x-y;
    
    //方式3:异或。原理:a^b^b = a, 即b^b=0,a^0=a;
    x^=y;
    y^=x;
    x^=y;
    

    比较了下速度,比较让人吃惊的是位运行的速度不是最快的,反而极慢

    int x = 100;
           int y = 200;
    
    //方式1:临时变量
    int size = Integer.MAX_VALUE;
    long s = System.currentTimeMillis();
    for (int i = 0; i < size; i++) {
        int z= x;
        x = y;
        y =z;
    }
    System.out.println(System.currentTimeMillis()-s);
    
    //方式2:不用临时变量
    s = System.currentTimeMillis();
    for (int i = 0; i < size; i++) {
        x = x+y;
        y = x-y;
        x = x-y;
    }
    System.out.println(System.currentTimeMillis()-s);
    
    
    //方式3:异或。原理:a^b^b = a, 即b^b=0,a^0=a;
    s = System.currentTimeMillis();
    for (int i = 0; i < size; i++) {
        x^=y;
        y^=x;
        x^=y;
    }
    System.out.println(System.currentTimeMillis()-s);
    /*
    output:
    2
    2
    2915
    */
    

    可见异或比前两者时间多了近3个数量级
    我分别使用三种方式,反编译后如下:

    //方式1
    public static void main(java.lang.String[]);
        Code:
           0: bipush        100
           2: istore_1
           3: sipush        200
           6: istore_2
           7: iload_1
           8: istore_3
           9: iload_2
          10: istore_1
          11: iload_3
          12: istore_2
          13: return
    
    //方式2:
      public static void main(java.lang.String[]);
        Code:
           0: bipush        100
           2: istore_1
           3: sipush        200
           6: istore_2
           7: iload_1
           8: iload_2
           9: iadd
          10: istore_1
          11: iload_1
          12: iload_2
          13: isub
          14: istore_2
          15: iload_1
          16: iload_2
          17: isub
          18: istore_1
          19: return
    
    //方式3:
     public static void main(java.lang.String[]);
        Code:
           0: bipush        100
           2: istore_1
           3: sipush        200
           6: istore_2
           7: iload_1
           8: iload_2
           9: ixor
          10: istore_1
          11: iload_2
          12: iload_1
          13: ixor
          14: istore_2
          15: iload_1
          16: iload_2
          17: ixor
          18: istore_1
          19: return:
    

    可见,方式1最简单,只涉及简单的load、store操作
    方式2、3的唯一不同在于一个是加减(iadd、isub),一个是异或,由此我猜测在jvm运行时,异或需要花更多的时间,具体不知道到底为什么。

    总结

    我们在使用中应该尽量用临时变量的方式,方式2存在溢出情况,方式3速度跟不上。
    不管是从性能上,还是从易读性上方式1都更好些。另外两种都是奇淫技巧,知道就行了。

  • 相关阅读:
    如何删除日志?
    sql lock
    生成DAL
    字符串ID替换
    精典SQL:分组合并列值
    SQL Server2005 XML数据类型基础
    Buckup
    SQL试题
    SQL处理表重复记录
    Left Join 中on与where的区别
  • 原文地址:https://www.cnblogs.com/XT-xutao/p/13200245.html
Copyright © 2020-2023  润新知