[英]Java optimization, gain from hashMap?
我已经给出了一些可爱的 Java代码,其中包含很多类似的内容(一个循环执行约150万次)。
code = getCode();
for (int intCount = 1; intCount < vA.size() + 1; intCount++)
{
oA = (A)vA.elementAt(intCount - 1);
if (oA.code.trim().equals(code))
currentName= oA.name;
}
从切换到以下内容后,我是否会看到速度显着提高
code = getCode();
//AMap is a HashMap
strCurrentAAbbreviation = (String)AMap.get(code);
编辑:VA的大小约为50.装饰甚至不应该是必要的,但肯定会是不错的调用50倍,而不是50 * 150万。 vA中的项目是唯一的。
编辑:在几个响应者的建议下,我对其进行了测试。 结果在底部。 多谢你们。
只有一种找出方法。
好吧,好吧,我测试了一下。
结果说明如下:
循环:18391ms散列:218ms
循环:18735ms哈希:234ms
循环:18359ms哈希:219ms
我想我会重构一下..
框架:
public class OptimizationTest {
private static Random r = new Random();
public static void main(String[] args){
final long loopCount = 1000000;
final int listSize = 55;
long loopTime = TestByLoop(loopCount, listSize);
long hashTime = TestByHash(loopCount, listSize);
System.out.println("Looping: " + loopTime + "ms");
System.out.println("Hash: " + hashTime + "ms");
}
public static long TestByLoop(long loopCount, int listSize){
Vector vA = buildVector(listSize);
A oA;
StopWatch sw = new StopWatch();
sw.start();
for (long i = 0; i< loopCount; i++){
String strCurrentStateAbbreviation;
int j = r.nextInt(listSize);
for (int intCount = 1; intCount < vA.size() + 1; intCount++){
oA = (A)vA.elementAt(intCount - 1);
if (oA.code.trim().equals(String.valueOf(j)))
strCurrentStateAbbreviation = oA.value;
}
}
sw.stop();
return sw.getElapsedTime();
}
public static long TestByHash(long loopCount, int listSize){
HashMap hm = getMap(listSize);
StopWatch sw = new StopWatch();
sw.start();
String strCurrentStateAbbreviation;
for (long i = 0; i < loopCount; i++){
int j = r.nextInt(listSize);
strCurrentStateAbbreviation = (String)hm.get(j);
}
sw.stop();
return sw.getElapsedTime();
}
private static HashMap getMap(int listSize) {
HashMap hm = new HashMap();
for (int i = 0; i < listSize; i++){
String code = String.valueOf(i);
String value = getRandomString(2);
hm.put(code, value);
}
return hm;
}
public static Vector buildVector(long listSize)
{
Vector v = new Vector();
for (int i = 0; i < listSize; i++){
A a = new A();
a.code = String.valueOf(i);
a.value = getRandomString(2);
v.add(a);
}
return v;
}
public static String getRandomString(int length){
StringBuffer sb = new StringBuffer();
for (int i = 0; i< length; i++){
sb.append(getChar());
}
return sb.toString();
}
public static char getChar()
{
final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i = r.nextInt(alphabet.length());
return alphabet.charAt(i);
}
}
嗯,是的,您很有可能会。 如果您具有良好的哈希码,则从HashMap检索将是恒定时间。
但是,您真正要找出的唯一方法就是尝试一下。
这取决于您的地图有多大,以及hashCode实现的良好程度(这样您就不会有大肠菌病)。
您实际上应该进行一些实际的分析,以确保是否需要进行任何修改,因为您可能最终会花费时间来修复未损坏的问题。
在我看来,真正要比elementAt调用突出的是每次迭代所进行的字符串修剪。 我的直觉告诉我,这可能是一个更大的瓶颈,但只有剖析才能真正看出来。
祝好运
我会说是的,因为以上内容似乎是对vA.size()的线性搜索。 VA多大?
为什么不使用类似YourKit之类的东西(或插入另一个探查器)来查看循环这部分的成本。
使用Map当然是一项改进,有助于以后维护该代码。
是否可以使用地图取决于(vector?)是否包含唯一代码。 给定的for循环会记住给定代码的列表中的最后一个对象,这意味着哈希不是解决方案。
对于较小(稳定)的列表大小,仅将列表转换为对象数组即可在提高可读性的基础上提高性能。
如果以上条件均不成立,请至少使用itarator检查列表,以提高可读性并提高性能。
要看。 你有多少内存?
我想速度要快得多,但是要对其进行分析。
我认为这里的主要因素是vA有多大,因为循环需要运行n次,其中n是vA的大小。 有了地图,无论vA有多大,都没有循环。 因此,如果n小,则改善将很小。 如果规模巨大,那么改善将是巨大的。 这是特别正确的,因为即使找到匹配的元素,循环仍然继续! 因此,如果您在200万个元素列表的元素1中找到匹配项,则仍然需要检查最后1,999,999个元素!
是的,几乎可以肯定会更快。 假设您的vA内容可以很好地散列,则平均循环25次(遍历50次)要比散列图查找慢。
但是,说到vA内容 ,将它们插入aMap时必须修剪它们,因为aMap.get(“ somekey”)不会找到键为“ somekey”的条目。
实际上,即使您不切换到哈希图解决方案,也应该在插入vA时这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.