軟體工程師的小事:到底要不要 Close

搭配 yield return 將資料列轉換成物件的資源使用差異

本範例情境為使用 DataReader 將資料列轉換成資料物件後回傳,並比較「使用 yield return」 或將「物件新增到集合後一次 return」在資源使用的差異

使用 Visual Studio 2017 的 Diagnostics Tools 工具觀察資源使用差異

將關注在記憶體使用量 Process Memory
文章環境
資料庫
Microsoft SQL Server
主控台應用程式
.NET Core Console Application (v2.1)

資料庫指令碼與範例程式碼可以在下列 Github 路徑中取得
txstudio/UseYieldReturnResourceUseage

準備資料

執行 init.sql 指令

將範例程式碼中的 init.sql 執行後會建立下面資料庫與資料表

透過 bcp 將 data.csv 資料匯入到資料表

bcp YieldReturnDb.dbo.SalesOrderDetailFromAdventureWorks2017 IN data.csv -c -S localhost -U sa -P Pa$$w0rd

本範例資料列資料筆數為 849219 筆

執行範例應用程式

依照 UseListReturnApp/UseYieldReturnApp 實作不同取得資料物件集合的方法,將回傳的物件集合透過 foreach 取得 rowguid 屬性(為求焦點明確不做額外的處理)

程式碼片段請參考下列連結
UseYieldReturnApp/Program.cs#L16

執行 UseListReturnApp 應用程式

本應用程式將讀取的每筆資料列轉換成物件後新增到物件集合後將物件集合進行回傳

程式碼片段請參考下列連結
UseListReturnApp/UseListReturnRepository.cs#L30

執行的資源使用量結果如下圖

最大記憶體使用為 231(MB) 並有多次的 GC 標記

執行 UseYieldReturnApp 應用程式

本應用程式將讀取的每筆資料列轉換成物件後透過 yield return 進行回傳

程式碼片段請參考下列連結
UseYieldReturnApp/UseYieldReturnRepository.cs#L25

執行的資源使用量結果如下圖

最大記憶體使用僅有 16(MB) 並有沒有 GC 標記

結論

使用 yield return 的記憶體資源使用相較之下是比較少的

關於 yield 的運作方式煩請參閱「仔細體會yield的甜美: yield介紹 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天」文章

參考資料

留言