您当前的位置:首页 > 计算机 > 编程开发 > 编程箴言

位运算实现数据交换你以为效率很高吗?

时间:02-04来源:作者:点击数:

使用临时变量实现数据交换,代码如下:

int a = 1,b = 2, temp = a;
temp = a;
a = b;
b = temp;
System.out.println("a = " + a + ", b = " + b); // a = 2, b = 1

使用位运算实现数据交换,代码如下:

int a = 1,b = 2;
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println("a = " + a + ", b = " + b); // a = 2, b = 1

看到这种位运算,一般大脑就会觉得高级,会觉得效率应该也比较高吧,其实并不然,实验如下:

private static void switchData(int[] bytes) {
    int temp;
    for (int i = 0; i < bytes.length; i+=2) {
        temp = bytes[i];
        bytes[i] = bytes[i + 1];
        bytes[i + 1] = temp;
    }
}

如上方法,功能为:依次从bytes数组中取出两位数据进行交换。下面我们实例对应的位运算方法:

private static void switchData(int[] bytes) {
    for (int i = 0; i < bytes.length; i+=2) {
        bytes[i] = bytes[i] ^ bytes[i + 1];
        bytes[i + 1] = bytes[i] ^ bytes[i + 1];
        bytes[i] = bytes[i] ^ bytes[i + 1];
    }
}

下面,我们定义一个比较大的数组对象,然后执行10次交换,并打印出每一次交换时使用的时间:

public static void main(String[] args) {
    int[] bytes = new int[10000_0000];
    for (int i = 0; i < 10; i++) {
        long start = System.currentTimeMillis();
        switchData(bytes);
        System.out.println("使用时间:" + (System.currentTimeMillis() - start));
    }
}

使用临时变量实现交换时,基本上使用时间为50毫秒上下,而使用位运算实现的交换时,使用时间差不多要70毫秒,这差距可是非常大的。

为什么我会想到这个问题,因为在做项目开发的时候,有一个应用使用到了摄像头,需要开启视频,Android手机摄像头传出的视频是很大的,需要压缩。Android摄像头传出的图片数据为原始数据(NV21格式),需要压缩为H264格式,而压缩为H264时,接收的参数为NV12数据,这时就需要把NV21转换为NV12,这两种格式都是YUV格式,不同点在于U和V的位置是相反的,所以转换格式就是把U和V的格式交换一下即可。当我们视频分辨率为1920 x 1080时,一张图片的大小为:byte[] onePicture = new byte[1920 x 1080 x 3 / 2],数据量相当的大,所以此时的数据交互如果用位运算那可就亏大发了,毫秒必争啊,为什么要争呢?因为要想不卡,视频需要1秒显示25张图片,1秒 / 25张 = 40毫秒,这就是说每张图片的处理时间如果在40毫秒以内就不会卡,假设你转换1张图片格式就花了40毫秒了,那你转换为格式还需要压缩呢,压缩完还要发送呢,这些都需要时间的,加起来就超过40毫秒了,那视频肯定就卡了,所以分秒必争啊这种情况。

那位运算的数据交换用在什么地方呢?用在那种内存很小,而且需要交换数据,并且交换次数并不多的场景。这种场景一般我们遇不到。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门