HashSet与List泛型之间的性能比较
搜索了一些文章,但谁也没有举出实例来证明HasSet和List之间谁的查询性能更好。自己动手证明一下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TimeControler;
namespace HashSetPerformance
{
class Program
{
static void Main(string[] args)
{
//设置最大值 以及查询数字
int maxNum = 9999999;
int serchNum = 9999993;
Console.WriteLine("maxNum:"+maxNum);
Console.WriteLine("searchNum"+serchNum);
//得到数据集
HashSet<int> hashSet = GetHashSet(maxNum);
List<int> list = GetList(maxNum);
//分别计算所需时间
TimeControl.Start();
hashSet.Contains(serchNum);
TimeControl.Stop();
Console.WriteLine("HashSet:"+TimeControl.GetMilliseconds());
TimeControl.Start();
list.Contains(serchNum);
TimeControl.Stop();
Console.WriteLine("List:"+TimeControl.GetMilliseconds());
Console.ReadLine();
}
private static HashSet<int> GetHashSet(int maxNum)
{
HashSet<int> hashSet = new HashSet<int>();
for (int i = 0; i < maxNum; i++)
{
hashSet.Add(i);
}
return hashSet;
}
private static List<int> GetList(int maxNum)
{
List<int> list = new List<int>();
for (int i = 0; i < maxNum; i++)
{
list.Add(i);
}
return list;
}
}
}
CASE 0: serchNum = 2777661 CASE 1: serchNum = 12345 CASE 2: serchNum = 9999993 —————————————————————————————- 上述数据说明,无序链表查询上相对List是比较稳定的,查阅一下List的源码
// Contains returns true if the specified element is in the List.
// It does a linear, O(n) search. Equality is determined by calling
// item.Equals().
//
public bool Contains(T item) {
if ((Object) item == null) {
for(int i=0; i<_size; i++)
if ((Object) _items[i] == null)
return true;
return false;
}
else {
EqualityComparer<T> c = EqualityComparer<T>.Default;
for(int i=0; i<_size; i++) {
if (c.Equals(_items[i], item)) return true;
}
return false;
}
}
for(int i=0; i<_size; i++) {
if (c.Equals(_items[i], item)) return true;
}
这段代码说明其内部依旧是按照索引顺序遍历全部元素 —————————————————————————————- 虽然HashSet并不存在键值之间的对应关系,但HashSet依旧遵循Hash算法,且在其内部也会产生HashCode。
/// <summary>
/// Checks if this hashset contains the item
/// </summary>
/// <param name="item">item to check for containment</param>
/// <returns>true if item contained; false if not</returns>
public bool Contains(T item) {
if (m_buckets != null) {
int hashCode = InternalGetHashCode(item);
// see note at "HashSet" level describing why "- 1" appears in for loop
for (int i = m_buckets[hashCode % m_buckets.Length] - 1; i >= 0; i = m_slots[i].next) {
if (m_slots[i].hashCode == hashCode && m_comparer.Equals(m_slots[i].value, item)) {
return true;
}
}
}
// either m_buckets is null or wasn't found
return false;
}
能看源码就是爽啊。。。