c# List實現原理


在研究前輩們寫的代碼,總是搞不明白。word文中引文的索引和引文列表中的索引對應關系是什么呢?是如何對應上的?我冥思苦想,昨天又系統地看了下代碼,才所有悟,所以記錄下我的探索過程。

如下圖所示:

      圖1

                                        圖2

圖1,是word文中引文,圖2是題錄引文列表,紅色的是索引,這兩個索引是要一一對應的。

 這段代碼實現的功能:過濾掉bib_List的重復項,然后初始化內存題錄表。

1   //bib_List 是題錄列表,Globals.BibTableAccessor._dictBibs是內存題錄列表字典,用來存儲word文檔的題錄列表。
2    for (int i = 0; i < bib_List.Count; i++)
3    {
4       if (!bib.Contains(bib_List[i]))
5        {
6            bib.Add(bib_List[i]);
7        }
8    }
9   Globals.BibTableAccessor._dictBibs[Globals.MemoryDataKey] = bib;
 1  Int32 i_BIndex=1;
 2  for (int i = 0; i < bib_List.Count; i++)
 3  {
 4    //初始化格式化內存表記錄
 5   MemoryData memData = new MemoryData();
 6   memData.BPhysicsID = i_BIndex;
 7   if (existBibs.ContainsKey(bib_List[i].BibliographyId))
 8   {
 9     //若有重復處理
10   }
11   else
12   {
13     memData.BLogicID = i_BIndex;
14     i_BIndex++;
15   }
16 }

圖1中的索引是根據 memData.BLogicID生成的,我們再看看引文列表的索引是根據什么生成的?

1  if (Globals.BibTableAccessor._dictBibs.ContainsKey(Globals.MemoryDataKey))
2  {
3     List<Bibliography> unquieBibliographies = this.GetUniqueBibliographies(Globals.BibTableAccessor._dictBibs[Globals.MemoryDataKey]);
4     this.CreateaReferencesList(cache, unquieBibliographies, journalStyle, wordStyle);
5 }

 

從上面的代碼可以看到  unquieBibliographies 這個來源正是內存中的題錄表,第4行代碼,正是實現引文列表的,它的內部實現是循環內存題錄表,然后根據循環的i變量來生成引文列表索引。

到這里,我就想,文中引文索引和引文列表的索引,都是和內存題錄表的存儲順序相關。那如果內存題錄表在第二次使用的時候,它的順序會不會變化?於是一個大膽的想法產生了:這個內存題錄表,在c#中是一個泛型List,那List的存儲在不排序的情況下到底會不會變呢?List是不是按我們Add的順序存儲,然后就不變呢?

為了揭開這些問題的答案,我偷偷地看了下List底層到底是怎么實現的?

 看到構造函數里面,原來是構造了一個空的數組,默認容量是4。難怪以前比較厲害的同學,告誡我們給List適當地初始容量,這樣會提供List效率。當時,一臉懵逼,為什么呢?現在看了代碼才明白,

 當我們Add一個元素的時候,判斷如果當前數組大小和元素的個數相等時,這時候要擴容,按照2倍的規則擴容的:

 

 其實,我覺得執行這個擴容代碼倒不耗費什么性能。真正耗費性能的,應該是不斷地向內存申請存儲空間,我覺得這個事情應該耗費性能。按照我的想法,就算申請存儲空間也不耗費性能,那微軟會怎么做呢?是在原來數組的基礎上擴展容量,還是新實例化了一個數組,把原來的數組元素拷貝過去?

我們繼續研究代碼,此刻我是一邊寫,一邊研究,還沒有吃中午飯。

 

看到這里的代碼,我覺得一陣欣喜,微軟的做法,就是新構造了一個數組,把元素拷貝過去。那為什么不在原來的基礎上擴容呢?我想了想,所謂數組,就是一組連續的存儲空間,那微軟要在原來的基礎上擴展,何談容易呢?萬一這段空間周邊沒有空間呢?那就干脆把這樣的困難的事情交給操作系統完成好了。

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM