นี่ไม่ใช่คำตอบสำหรับคำถามของคุณ แต่ฉันมีคลาสที่เพิ่มประสิทธิภาพของมี () ในคอลเล็กชัน ฉันซับคลาสคิวและเพิ่มพจนานุกรมที่แมปรหัสแฮชกับรายการวัตถุ Dictionary.Contains()
ฟังก์ชั่นคือ O (1) ในขณะที่List.Contains()
, Queue.Contains()
และStack.Contains()
เป็น O (n)
ประเภทค่าของพจนานุกรมคือคิวที่ถืออ็อบเจ็กต์ที่มีแฮชโค้ดเดียวกัน ผู้เรียกสามารถจัดหาคลาสอ็อบเจ็กต์แบบกำหนดเองที่ใช้ IEqualityComparer คุณสามารถใช้รูปแบบนี้สำหรับ Stacks หรือ Lists รหัสจะต้องมีการเปลี่ยนแปลงเพียงเล็กน้อย
private class HashQueue<T> : Queue<T>
{
private readonly IEqualityComparer<T> _comp;
public readonly Dictionary<int, Queue<T>> _hashes;
public HashQueue(IEqualityComparer<T> comp = null) : base()
{
this._comp = comp;
this._hashes = new Dictionary<int, Queue<T>>();
}
public HashQueue(int capacity, IEqualityComparer<T> comp = null) : base(capacity)
{
this._comp = comp;
this._hashes = new Dictionary<int, Queue<T>>(capacity);
}
public HashQueue(IEnumerable<T> collection, IEqualityComparer<T> comp = null) : base(collection)
{
this._comp = comp;
this._hashes = new Dictionary<int, Queue<T>>(base.Count);
foreach (var item in collection)
{
this.EnqueueDictionary(item);
}
}
public new void Enqueue(T item)
{
base.Enqueue(item);
this.EnqueueDictionary(item);
}
private void EnqueueDictionary(T item)
{
int hash = this._comp == null ? item.GetHashCode() : this._comp.GetHashCode(item);
Queue<T> temp;
if (!this._hashes.TryGetValue(hash, out temp))
{
temp = new Queue<T>();
this._hashes.Add(hash, temp);
}
temp.Enqueue(item);
}
public new T Dequeue()
{
T result = base.Dequeue();
int hash = this._comp == null ? result.GetHashCode() : this._comp.GetHashCode(result);
Queue<T> temp;
if (this._hashes.TryGetValue(hash, out temp))
{
temp.Dequeue();
if (temp.Count == 0)
this._hashes.Remove(hash);
}
return result;
}
public new bool Contains(T item)
{
int hash = this._comp == null ? item.GetHashCode() : this._comp.GetHashCode(item);
return this._hashes.ContainsKey(hash);
}
public new void Clear()
{
foreach (var item in this._hashes.Values)
item.Clear();
this._hashes.Clear();
base.Clear();
}
}
การทดสอบอย่างง่ายของฉันแสดงให้เห็นว่าฉันHashQueue.Contains()
วิ่งเร็วกว่าQueue.Contains()
ไฟล์. การรันโค้ดทดสอบโดยตั้งค่านับเป็น 10,000 ใช้เวลา 0.00045 วินาทีสำหรับเวอร์ชัน HashQueue และ 0.37 วินาทีสำหรับเวอร์ชันคิว ด้วยจำนวน 100,000 ครั้งเวอร์ชัน HashQueue ใช้เวลา 0.0031 วินาทีในขณะที่คิวใช้เวลา 36.38 วินาที!
นี่คือรหัสทดสอบของฉัน:
static void Main(string[] args)
{
int count = 10000;
{
var q = new HashQueue<int>(count);
for (int i = 0; i < count; i++)
q.Enqueue(i);
System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
bool contains = q.Contains(i);
}
sw.Stop();
Console.WriteLine(string.Format("HashQueue, {0}", sw.Elapsed));
}
{
var q = new Queue<int>(count);
for (int i = 0; i < count; i++)
q.Enqueue(i);
System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
bool contains = q.Contains(i);
}
sw.Stop();
Console.WriteLine(string.Format("Queue, {0}", sw.Elapsed));
}
Console.ReadLine();
}