use*_*373 2 java performance arraylist hashmap
我原以为HashMaps对于单个值的随机访问比ArrayLists 更快...也就是说,这HashMap.get(key)应该比ArrayList.get(index)仅仅因为ArrayList必须遍历集合的每个元素以达到其值而更快,而HashMap不是.你知道,O(1)vs O(n)和所有这一切.
编辑:所以我对HashMaps的理解是不充分的,因此我的困惑.此代码的结果符合预期.感谢您的解释.
所以我决定用百灵鸟来测试它.这是我的代码:
import java.util.HashMap;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class Testing
{
public static void main(String[] args)
{
ArrayList<SomeClass> alist = new ArrayList<>();
HashMap<Short, SomeClass> hmap = new HashMap<>(4000, (float).75);
ListIterator<SomeClass> alistiterator = alist.listIterator();
short j = 0;
do
{
alistiterator.add(new SomeClass());
j++;
}
while(j < 4000);
for (short i = 0; i < 4000; i++)
{
hmap.put(i, new SomeClass());
}
boolean done = false;
Scanner input = new Scanner(System.in);
String blargh = null;
do
{
System.out.println("\nEnter 1 to run iteration tests.");
System.out.println("Enter w to run warmup (recommended)");
System.out.println("Enter x to terminate program.");
try
{
blargh = input.nextLine();
}
catch (NoSuchElementException e)
{
System.out.println("Uh, what? Try again./n");
continue;
}
switch (blargh)
{
case "1":
long starttime = 0;
long total = 0;
for (short i = 0; i < 1000; i++)
{
starttime = System.nanoTime();
iteratearraylist(alist);
total += System.nanoTime() - starttime;
}
total = (long)(total * .001);
System.out.println(total + " ns: iterating sequentially"
+ " through ArrayList");
total = 0;
for (short i = 0; i< 1000; i++)
{
starttime = System.nanoTime();
iteratearraylistbyget(alist);
total += System.nanoTime() - starttime;
}
total = (long)(total * .001);
System.out.println(total + " ns: iterating sequentially"
+ " through ArrayList via .get()");
total = 0;
for (short i = 0; i< 1000; i++)
{
starttime = System.nanoTime();
iteratehashmap(hmap);
total += System.nanoTime() - starttime;
}
total = (long)(total * .001);
System.out.println(total + " ns: iterating sequentially"
+ " through HashMap via .next()");
total = 0;
for (short i = 0; i< 1000; i++)
{
starttime = System.nanoTime();
iteratehashmapbykey(hmap);
total += System.nanoTime() - starttime;
}
total = (long)(total * .001);
System.out.println(total + " ns: iterating sequentially"
+ " through HashMap via .get()");
total = 0;
for (short i = 0; i< 1000; i++)
{
starttime = System.nanoTime();
getvaluebyindex(alist);
total += System.nanoTime() - starttime;
}
total = (long)(total * .001);
System.out.println(total + " ns: getting end value"
+ " from ArrayList");
total = 0;
for (short i = 0; i< 1000; i++)
{
starttime = System.nanoTime();
getvaluebykey(hmap);
total += System.nanoTime() - starttime;
}
total = (long)(total * .001);
System.out.println(total + " ns: getting end value"
+ " from HashMap");
break;
case "w":
for (int i = 0; i < 60000; i++)
{
iteratearraylist(alist);
iteratearraylistbyget(alist);
iteratehashmap(hmap);
iteratehashmapbykey(hmap);
getvaluebyindex(alist);
getvaluebykey(hmap);
}
break;
case "x":
done = true;
break;
default:
System.out.println("Invalid entry. Please try again.");
break;
}
}
while (!done);
input.close();
}
public static void iteratearraylist(ArrayList<SomeClass> alist)
{
ListIterator<SomeClass> tempiterator = alist.listIterator();
do
{
tempiterator.next();
}
while (tempiterator.hasNext());
}
public static void iteratearraylistbyget(ArrayList<SomeClass> alist)
{
short i = 0;
do
{
alist.get(i);
i++;
}
while (i < 4000);
}
public static void iteratehashmap(HashMap<Short, SomeClass> hmap)
{
Iterator<HashMap.Entry<Short, SomeClass>> hmapiterator =
map.entrySet().iterator();
do
{
hmapiterator.next();
}
while (hmapiterator.hasNext());
}
public static void iteratehashmapbykey(HashMap<Short, SomeClass> hmap)
{
short i = 0;
do
{
hmap.get(i);
i++;
}
while (i < 4000);
}
public static void getvaluebykey(HashMap<Short, SomeClass> hmap)
{
hmap.get(3999);
}
public static void getvaluebyindex(ArrayList<SomeClass> alist)
{
alist.get(3999);
}
}
Run Code Online (Sandbox Code Playgroud)
和
public class SomeClass
{
int a = 0;
float b = 0;
short c = 0;
public SomeClass()
{
a = (int)(Math.random() * 100000) + 1;
b = (float)(Math.random() * 100000) + 1.0f;
c = (short)((Math.random() * 32000) + 1);
}
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,代码似乎分阶段热身.我已经确定的最后阶段是在所有方法的大约120,000次迭代之后.无论如何,在我的测试机器上(AMD x2-220,L3 + 1额外核心解锁,3.6 ghz,2.1 ghz NB),真正跳出来的数字是最后两个报道.即,().get()的最后一次输入所花费的时间以及与短键相关的值所花费的时间.ArrayListindex == 3999.get()3999
在2-3个预热周期后,测试显示ArrayList.get()大约需要56 ns,而HashMap.get()大约需要68 ns.那是 ...不是我的预期.我的HashMap所有人都被碰撞了吗?所有密钥条目都应该自动提交给Shorts,它们应该报告它们存储的短值以响应.hashcode(),因此所有的哈希码都应该是唯一的.我认为?
即使没有热身,ArrayList.get()它仍然更快.这与我在别处看到的所有内容相反,例如这个问题.当然,我也读过,ArrayList用a 遍历a ListIterator比.get()在循环中使用更快,显然,情况并非如此...
ArrayList必须遍历集合的每个元素以达到其值
这不是真的。ArrayList由支持恒定时间get操作的数组支持。
HashMap的get,在另一方面,第一绝散列它的参数,那么它必须遍历桶到的散列码对应,在桶中用于与所述给定键相等性测试的每个元素。通常,这比仅索引数组要慢。
ArrayList.get(index)acctualy使用常量时间,因为ArrayList它由数组支持,因此它只在bacing数组中使用该索引.在最坏的情况下ArrayList.contains(Object)是一个长期的操作O(n).
哈希映射在检索已知索引处的某些内容时速度不快.如果您按已知顺序存储内容,列表将获胜.
但是,不是将所有内容插入到列表1-4000中的示例,而是以完全随机顺序执行此操作.现在要从列表中检索正确的项目,您必须逐个检查每个项目以查找正确的项目.但是要从hashmap中检索它,你需要知道的只是插入它时给它的关键.
所以,你应该将Hashmap.get(i)与之比较
for(Integer i : integerList)
if(i==value)
//found it!
Run Code Online (Sandbox Code Playgroud)
然后你会看到hashmap的真正效率.
| 归档时间: |
|
| 查看次数: |
7677 次 |
| 最近记录: |