什么是更好的?两个哈希映射或一个使用类?

时间:2015-08-13 21:38:24

标签: java

我目前正在编写一些我非常关注性能和内存使用情况的内容。

我想知道这个问题,我正在努力做出决定。想象一下这种情况:

我需要将某个Class(Location)和一个Integer关联到一个String(让我们说一个名字)。所以名称有一个Id和一个位置......

最好的方法是什么?

首先:创建两个哈希映射

HashMap<String, Location> one = new HashMap<String, Location>
HashMap<String, Integer> two = new HashMap<String, Integer>

第二:仅使用一个hashmap并创建一个新类

HashMap<String, NewClass> one = new HashMap<String, NewClass>

其中NewClass包含:

class NewClass {

    Location loc;
    Integer int;
}

2 个答案:

答案 0 :(得分:2)

如果您希望每个String都与BOTH位置和整数耦合,请使用新类,调试和维护将更加容易,因为它是有意义的。字符串X连接到位置和整数。它可以确保您减少错误(例如只插入其中一个,或只删除一个),并且更易读。

如果关联松散,并且某些字符串可能只需要位置,而某些字符串只需要整数 - 使用两个映射可能更可取,因为未来的代码读者(包括您在3个月内)将无法理解这是什么新的class以及String X需要有位置的原因。

TL; DR:

  • String->MyClass如果每个字符串始终与位置和整数
  • 相关联
  • String->Integer, String->Location如果每个字符串独立地与位置和整数相关联。

答案 1 :(得分:2)

如果你总是需要同时检索Id和Location,第一种方法需要2次Hash查找,而第二种方法只需要1次。在这种情况下,第二种方法应该有更好的性能。

为了测试我做了下面的简单测试:

// create 2 hashes with 1M entries
for (int i = 0; i < 1000000; i++){
    String s = new BigInteger(80, random).toString(32);
    hash1.put(s, s);
    hash2.put(s, new BigInteger(80, random).intValue());
}

// create 1 hash with 1M entries
for (int i = 0; i < 1000000; i++){
    String s = new BigInteger(80, random).toString(32);
    NewClass n = new NewClass();
    n.i = new BigInteger(80, random).intValue();
    n.loc = s;
    hash3.put(s, n);
}

// 5M lookups
long start = new Date().getTime();
for (int i = 0; i < 5000000; i++){
    String s = "AAA";
    hash1.get(s);
    hash2.get(s);
}
System.out.println("Approach 1 (2 hashes): " + (new Date().getTime() - start));

// 5M lookups
long start2 = new Date().getTime();
for (int i = 0; i < 5000000; i++){
    String s = "BBB";
    hash3.get(s);
}
System.out.println("Approach 2 (1 hash): " + (new Date().getTime() - start2));

在我的计算机上运行,​​结果是:

  • 方法1(2个哈希):37毫秒
  • 方法2(1哈希):18毫秒

测试非常简单,如果你要考虑严重的性能问题,你应该深入研究这个问题,考虑内存占用,对象创建成本等其他方面。但是,无论如何,使用2个哈希值将增加总查找时间。