C# DataTable與List讀寫效能測試
阿新 • • 發佈:2021-06-23
最近看見同事在寫需要非常多次遍歷的演算法,發現DataTable的讀取速度竟然吊打List
於是我做了個3千萬條資料的讀寫效能測試
using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Runtime.InteropServices; namespace ConsoleApp1 { class Program { static void Main() { Console.WriteLine("---3kw資料讀寫測試---"); DataTable dt = new DataTable(); Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < 30000000; i++) dt.Rows.Add(); sw.Stop(); Console.WriteLine($"DataTable 空行寫入 {sw.ElapsedMilliseconds} ms"); List<object> list = new List<object>(); sw.Restart(); for (int i = 0; i < 30000000; i++) list.Add(new object()); sw.Stop(); Console.WriteLine($"List<T> 空行寫入 {sw.ElapsedMilliseconds} ms"); sw.Restart(); foreach (var item in dt.Rows) { } sw.Stop(); sw.Restart(); Console.WriteLine($"DataTable 讀取 {sw.ElapsedMilliseconds} ms"); foreach (var item in list) { } sw.Stop(); Console.WriteLine($"List<T> 讀取 {sw.ElapsedMilliseconds} ms"); sw.Restart(); for (int i = dt.Rows.Count - 1; i >= 0; i--) dt.Rows.RemoveAt(i); sw.Stop(); Console.WriteLine($"DataTable 刪除 {sw.ElapsedMilliseconds} ms"); sw.Restart(); for (int i = list.Count - 1; i >= 0; i--) list.RemoveAt(i); sw.Stop(); Console.WriteLine($"List<T> 刪除 {sw.ElapsedMilliseconds} ms"); Console.ReadLine(); } } }
可以看到在寫入和刪除時,List效能是碾壓DataTable的,
但是List內部實現是基於陣列的資料結構,理論上位移下標的速度是高於連結串列等資料結構,為什麼讀取速度卻被DataTable吊打呢?
原因是因為DataTable在索引下標時是使用的紅黑二叉樹實現,
博主曾看過一篇紅黑二叉樹的效能測試,大概是1億條資料索引到某條資料只需要計算21次,
大家有興趣可以搜尋一下紅黑二叉樹,資料結構與演算法還是很重要的必修課。