• 首页
  • 关于

我自然

标记档案: 比较

Java使用”指针”快速比较字节

在 2012年3月16日 上公布 作者为 yankay

如何才能快速比较两个字节数组呢?我将问题描述成下面的接口:

 
public int compareTo(byte[] b1, int s1, int l1, byte[] b2, int s2,int l2);

最直观的做法是同时遍历两个数组,两两比较。

 
public int compareTo(byte[] buffer1, int offset1, int length1,
		byte[] buffer2, int offset2, int length2) {
	// Short circuit equal case
	if (buffer1 == buffer2 && offset1 == offset2
		&& length1 == length2) {
		return 0;
	}
	// Bring WritableComparator code local
	int end1 = offset1 + length1;
	int end2 = offset2 + length2;
	for (int i = offset1, j = offset2; i 

如果事情这么简单就结束了,就没有意思了。

如果要提升性能,可以做循环展开等等优化,但这些优化应该依赖JVM来做,新的JVM可以做的很好。那还有什么办法可以提高性能呢?
可以将字节数组合并!!上面的例子中,每个byte被迫转型成了int,再比较。其实我们可以将8个byte转换成一个long,在比较long,这样效果会不会好些?用什么方法转换才是最优的?

 
long sun.misc.Unsafe.getLong(Object o,int offset)

Java提供了一个本地方法,可以最快最好转换byte与long。该函数是直接访问一个对象的内存,内存地址是对象指针加偏移量,返回该地址指向的值。有人说Java很安全,不可以操作指针,所以有的时候性能也不高。其实不对,有了这个Unsafe类,Java一样也不安全。所以Unsafe类中的方法都不是public的,不过没关系,我们有反射。言归正传,下面是使用这种技术手段的实现代码。

 
public int compareTo(byte[] buffer1, int offset1, int length1,
		byte[] buffer2, int offset2, int length2) {
	// Short circuit equal case
	if (buffer1 == buffer2 && offset1 == offset2
			&& length1 == length2) {
		return 0;
	}
	int minLength = Math.min(length1, length2);
	int minWords = minLength / Longs.BYTES;
	int offset1Adj = offset1 + BYTE_ARRAY_BASE_OFFSET;
	int offset2Adj = offset2 + BYTE_ARRAY_BASE_OFFSET;

	/*
	 * Compare 8 bytes at a time. Benchmarking shows comparing 8
	 * bytes at a time is no slower than comparing 4 bytes at a time
	 * even on 32-bit. On the other hand, it is substantially faster
	 * on 64-bit.
	 */
	for (int i = 0; i >> n) & 0xFFL) - ((rw >>> n) & 0xFFL));
		}
	}

	// The epilogue to cover the last (minLength % 8) elements.
	for (int i = minWords * Longs.BYTES; i 

实现比原来复杂了一些。但这次一次可以比较8个字节了。这种getLong函数和系统的字节序是紧紧相关的,如果是小端序操作起来有点麻烦,代码先省略掉。这样操作实际效果如何?我们需要对比测试下。对比两个1M的字节数组,如果使用第一个版本,每次比较平均需要2.5499ms,如果使用第二个版本,需要0.8359ms,提升了3倍。对应这种CPU密集型的操作,这样的提升可是很可观的。

如果要提升性能,使用Unsafe直接访问内存也是不错的选择。

文章分类 软件技术 | 标签: Java, Java字节数组比较, Java字节比较, 字节, 比较 | 发表评论 |

近期文章

  • 听说 Docker 被 kubenetes 抛弃了,怎么办?containerd
  • 公告 – 博客重开了
  • CloudFoundry v2面面谈,内赠MicroCFv2福利
  • Docker能够运行任何应用的“PaaS”云
  • Scala Tour – 精选

近期评论

  • [整理]完美哈希函数(Perfect Hash Function) - 高性能架构探索发表在《最小完美哈希函数简介》
  • Scala Tour – 精选 - Java天堂发表在《Scala Tour – 精选》
  • Golang适合高并发场景的原因分析 - 站壳网发表在《Go-简洁的并发》
  • HBase 官方文档 – 源码巴士发表在《Windows下eclipse的 C++环境配置》
  • Go-简洁的并发-点开发表在《Go-简洁的并发》

归档

  • 2021年6月
  • 2021年3月
  • 2014年2月
  • 2013年9月
  • 2013年5月
  • 2013年1月
  • 2012年11月
  • 2012年9月
  • 2012年8月
  • 2012年3月
  • 2012年2月
  • 2012年1月
  • 2011年11月
  • 2011年10月
  • 2011年9月
  • 2010年10月
  • 2010年8月
  • 2010年7月
  • 2010年6月
  • 2010年5月
  • 2010年4月
  • 2010年3月
  • 2010年2月
  • 2010年1月
  • 2009年10月
  • 2009年9月
  • 2009年8月
  • 2009年7月
  • 2009年6月
  • 2008年10月
  • 2008年8月
  • 2008年7月
  • 2008年6月

分类目录

  • 家庭生活
  • 未分类
  • 每日心得
  • 软件技术

友情链接

  • DaoCloud Enterprise
  • DaoCloud 云原生一体机

CyberChimps WordPress Themes

沪ICP备2021008917号-1 © 颜开