有時我們希望復用一個Dictionary的時候,可以Clear()也可以,直接new一個新的對象,
兩者到底是哪個劃算呢?
我們看程序:
private void Experiment() { System.Diagnostics.Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); //Dictionaryaa = new Dictionary (); for (var loop = 0; loop < 30000; loop++) { Dictionary aa = new Dictionary (); for (var i = 0; i < 10000; i++) { aa.Add(i,i); } //aa.Clear(); } stopwatch.Stop(); Console.WriteLine("All timeL:"+stopwatch.Elapsed.TotalSeconds); }
數據結果如下:
使用Clear()時間為6秒。而使用new object的方法,時間為20秒,我覺得只所以這樣
是因為NEW object的方案中,需要執行很多次Resize的操作。
這些東西看基類代碼如下:
Add操作如下:
public void Add(TKey key, TValue value) { this.Insert(key, value, true); }
其調用Insert操作,代碼如下:
private void Insert(TKey key, TValue value, bool add) { int freeList; if (key == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); } if (this.buckets == null) { this.Initialize(0); } int num = this.comparer.GetHashCode(key) & 0x7fffffff; int index = num % this.buckets.Length; for (int i = this.buckets[index]; i >= 0; i = this.entries[i].next) { if ((this.entries[i].hashCode == num) && this.comparer.Equals(this.entries[i].key, key)) { if (add) { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate); } this.entries[i].value = value; this.version++; return; } } if (this.freeCount > 0) { freeList = this.freeList; this.freeList = this.entries[freeList].next; this.freeCount--; } else//散列已滿 { if (this.count == this.entries.Length) { this.Resize();//為散列重新開辟一塊兒內存空間 index = num % this.buckets.Length; } freeList = this.count; this.count++; } this.entries[freeList].hashCode = num; this.entries[freeList].next = this.buckets[index]; this.entries[freeList].key = key; this.entries[freeList].value = value; this.buckets[index] = freeList; this.version++; }
Resize()如下:
private void Resize() { int prime = HashHelpers.GetPrime(this.count * 2); int[] numArray = new int[prime];//開辟新的數組 for (int i = 0; i < numArray.Length; i++) { numArray[i] = -1; } Entry[] destinationArray = new Entry [prime];//開辟新的數組 Array.Copy(this.entries, 0, destinationArray, 0, this.count); for (int j = 0; j < this.count; j++) { int index = destinationArray[j].hashCode % prime; destinationArray[j].next = numArray[index]; numArray[index] = j; } this.buckets = numArray; this.entries = destinationArray; }