[.NET]輕量又兼具效能的ORM Framework - Dapper
最近再處理物件和資料對應效能問題,
同時改寫自己的Code Generation小工具,
在找如何提高ORM效能的方法時,
讓我無意見發現這套強大的ORM Framework - Dapper 。
我看網頁上所寫的效能真的有讓我嚇到,
讀取速度快接近IDataReader( 我 實測Dapper 後,發現更快),
但我真正在意的是物件和資料對應效能問題,
我大概去追了一下 Dapper 在處理序列化所使用的方法,
發現它使用 ILGenerator.Emit Method 來快速產生object (Reflection IDataReader ),
就連Linq 2 SQL CompiledQuery 效能都沒 Dapper 來的屌,
而且這各Dapper.dll只有小小的59KB,使用方法也很簡單。
經過自己實測50000筆資料對應,真的要給 Dapper Mapping 大大一個讚,
下面是測試結果和程式碼。
使用 Dapper
string connstr = ConfigurationManager.ConnectionStrings["Develop"].ToString();
string sql = @"select top(50000) * from AP_LOG";
string mycount = string.Empty;
Stopwatch sw = new Stopwatch();
sw.Reset();
using (SqlConnection connection = new SqlConnection(connstr))
{
// using Dapper
sw.Start();
var myquery = connection.Query<AP_LOG>(sql, null);
sw.Stop();
Console.WriteLine("筆數:{0},時間(ms):{1}", myquery.Count().ToString(), sw.ElapsedMilliseconds.ToString());
Console.ReadLine();
}
第一次
第二次
第三次
使用自定義RowMapping Method(Reflection IDataReader)
string connstr = ConfigurationManager.ConnectionStrings["Develop"].ToString();
string sql = @"select top(50000) * from AP_LOG";
string mycount = string.Empty;
Stopwatch sw = new Stopwatch();
sw.Reset();
using (SqlConnection connection = new SqlConnection(connstr))
{
// using Dapper
//sw.Start();
//var myquery = connection.Query<AP_LOG>(sql, null);
//sw.Stop();
//Console.WriteLine("筆數:{0},時間(ms):{1}", myquery.Count().ToString(), sw.ElapsedMilliseconds.ToString());
//Console.ReadLine();
// using custom mapping
connection.Open();
using (SqlCommand command = new SqlCommand(sql, connection))
{
sw.Start();
SqlDataReader dr = command.ExecuteReader();
mycount = RowMapping(dr);
sw.Stop();
}
Console.WriteLine("筆數:{0},時間(ms):{1}", mycount.ToString(), sw.ElapsedMilliseconds.ToString());
Console.ReadLine();
}
private static string RowMapping(IDataReader dr)
{
List<AP_LOG> ap_logs = new List<AP_LOG>();
while (dr.Read())
{
AP_LOG ap_log = new AP_LOG();
for (int i = 0; i < dr.FieldCount; i++)
{
PropertyInfo property = ap_log.GetType().GetProperty(dr.GetName(i));
property.SetValue(ap_log, dr.IsDBNull(i) ? "null" : dr.GetValue(i), null);
}
ap_logs.Add(ap_log);
}
return ap_logs.Count.ToString();
}
第一次
第二次
第三次
結果
方法 | 平均時間(ms) |
Dapper | 988 |
自定義RowMapping | 1991 |
測試完後,看來自己套用 Dapper 是無法避免的(個人.NET等級無法和 Dapper 相比...哀),
有種相見恨晚的感覺阿
參考