开源的高性能Java集合:GNU Trove介绍

来源:互联网 发布:学校网络系统集成方案 编辑:程序博客网 时间:2024/06/11 22:52

看过openNLP源码的人或许会注意到代码里经常引入import gnu.trove.*; 好奇之余,进行了资料搜集和总结。

Trove 是一个快速、轻量级 Collection 类的集合。Trove 提供所有标准 java.util Collections 类的更快的版本以及能够直接在原语(primitive)(例如包含 int 键或值的 Map 等)上操作的 Collections 类的版本。即它是一种开放源代码的 Java 集合包,提供了核心 Java 集合类的高效替代品,特别针对于实现其键或值是基本类型的集合
Trove 中有许许多多的高效集合,除了那 81 种不同的 HashMap 版本之外(比如 TIntIntHashMapTIntObjectHashMap 等),还有 List Set 类可以存储基本类型(如TIntHashSetTFloatArrayList 等)。这种体系结构甚至允许你插入自己的散列策略,以便选择对你的数据集而言可能更有效(或者更灵活)的算法。当然,支持灵活的散列算法也要付出性能代价 —— 如果散列映射成为瓶颈,很可能是因为大量地使用它,这意味着散列函数被反复不断地调用。因此,散列函数中每一点多余的开销都可能成为瓶颈。(顺便说一下,如果散列函数足够简单,JIT 编译器就可能将其编译成内联函数,这样在支持灵活的散列策略的同时又不会带来额外的开销)

trove是轻量级实现java.util Collections API的第三方开源项目 官网: http://trove.starlight-systems.com/overview trove相比jdk原生的集合类有三个优势: 1、更高的性能 2、更底的内存消耗 3、除了实现原生Collections API并额外提供更强大的功能。

集合是java编程最常用的API之一,把项目的集合对象改用trove替换就能获得性能提升和内存的节省。 这是对一个项目底成本的优化方案。

下面二段代码分别测试trove和原生的集合的性能:

1. trove

public void testIterator(){ TIntObjectMap map = new TIntObjectHashMap(); for( int i = 0; i < 1000; i++){ Game g = new Game(); g.setName("最终幻想"+ i); g.setSize(15000 + (i << 3)); g.setCtDate( new Date()); map.put(i, g);} int size = map.size(); TIntObjectIterator it = map.iterator(); for( int i = size; i > 0; i--){it.advance(); System. out.println(it.key() +"="+ it.value()); if(it.key() == 3){ Game g = new Game(); g.setName("最终幻想13"); g.setSize(15000 + (i << 3)); g.setCtDate( new Date());it.setValue(g);}} System. out.println("======================================="); System. out.println(map.get(3));}

2. HashMap

public void testIterator(){ Map map = new HashMap(); for( int i = 0; i < 1000; i++){ Game g = new Game(); g.setName("最终幻想"+ i); g.setSize(15000 + (i << 3)); g.setCtDate( new Date()); map.put(i, g);} Set set = map.entrySet(); for( Iterator it = set.iterator(); it.hasNext(); ){ Entry e = (Entry )it.next(); System. out.println(e.getKey() +"="+ e.getValue()); if(((Integer)e.getKey()).intValue() == 3){ Game g = new Game(); g.setName("最终幻想13");g.setSize(18000); g.setCtDate( new Date());e.setValue(g);}} System. out.println("======================================="); System. out.println(map.get(3));}

两段的测试结果,trove花费0.001s,HashMap花费0.090s trove的测试代码使用其Map额外提供的iterator进行遍历,当然他也支持通过entrySet方式遍历。 使用SizeOf.jar计算上面两段的map占用内存的大小,trove占用214024byte,HashMap占用250128byte,可见内存方面节省的比率并是很大。 从官方下载的API中可以看中trove根据基础的数据类型实现了Map、List和Set,比如TIntObjectHashMap其key只能是int, value是继承Object的所有对象;TIntList只能存入int;TIntSet只能存入int。 在java里有些对象的hashCode和equals方法不能被覆盖(比如:String和数组),以这种对象为Map的key时就不能随心所欲,trove的提供的custom map可以解除这种约束,只需要实现HashingStrategy接口传递给Map,Map判断key是否相同时调用HashingStrategy的computeHashCode和equals代替object自身的hashCode和equals,以下是官网一个例子 For example, this code:

char[] foo, bar; foo = new char[] {'a','b','c'}; bar = new char[] {'a','b','c'}; System.out.println(foo.hashCode() == bar.hashCode() ?"equal":"not equal"); System.out.println(foo.equals(bar) ?"equal":"not equal");

produces this output: not equal not equal And so an entry stored in a java.util.HashMap with foo as a key could not be retrieved with bar, since there is no way to override hashCode() or equals() on language array objects. In a gnu.trove.THashMap, however, you can implement a TObjectHashingStrategy to enable hashing on arrays:

class CharArrayStrategy implements TObjectHashingStrategy {  public int computeHashCode(Object o) {  char[] c = (char[])o;  // use the shift-add-xor class of string hashing functions  // cf. Ramakrishna and Zobel,"Performance in Practice  // of String Hashing Functions" int h = 31; // seed chosen at random  for (int i = 0; i < c.length; i++) { // could skip invariants  h = h ^ ((h << 5) + (h >> 2) + c[i]); // L=5, R=2 works well for ASCII input } return h; } public boolean equals(Object o1, Object o2) {  char[] c1 = (char[])o1;  char[] c2 = (char[])o2;  if (c1.length != c2.length) { // could drop this check for fixed-length keys  return false; } for (int i = 0, len = c1.length; i < len; i++) { // could skip invariants  if (c1[i] != c2[i]) {  return false; }} return true; }}

总结: Trove是很值得了解和使用的一个开源项目,而且容易上手,值得学习。





 

0 0
原创粉丝点击