Advertisement
Guest User

Raw .NET Data Access / ORM Fetch benchmarks

a guest
Dec 8th, 2013
1,723
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 24.58 KB | None | 0 0
  1. // Raw results of fetch benchmark
  2. // specifics:
  3. // - SQL Server 2005 on VM on separate machine, connected via 100BaseT network
  4. // - A single entity type was fetched, no hierarchies, inheritance or other special aspects
  5. // - Benchcode run in release build on .NET 4.5.1 on Windows 8.0 32bit on core2Quad @2.4ghz
  6. // - DB was warmed up with lots of runs before these results were gathered
  7. // - Benchcode, lowlevel DB client code was warmed up with not-used fetch results.
  8. // - The average results ignore the slowest and fastest code
  9. // - No tweaks were added for any framework, stock settings.
  10. // - Every ORM, if applicable, had the full AdventureWorks model mapped, all 67 entities
  11. // - Focus was deliberately set on entity materialization speed.
  12. // ----------------------------------------------------------------------------------------------
  13. Warming up DB, DB client code and CLR
  14. ------------------------------------------
  15. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 626ms
  16. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 583ms
  17. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 584ms
  18. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 600ms
  19. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 587ms
  20. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 576ms
  21. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 580ms
  22. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 591ms
  23. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 593ms
  24. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 579ms
  25.  
  26. Starting benchmarks
  27. ------------------------------------------
  28. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 6050ms
  29. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 3563ms
  30. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 3433ms
  31. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 3443ms
  32. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 3470ms
  33. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 3482ms
  34. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 3489ms
  35. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 3375ms
  36. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 3407ms
  37. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 3570ms
  38. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()'. Took: 690ms
  39. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()'. Took: 700ms
  40. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()'. Took: 645ms
  41. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()'. Took: 722ms
  42. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()'. Took: 638ms
  43. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()'. Took: 748ms
  44. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()'. Took: 676ms
  45. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()'. Took: 706ms
  46. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()'. Took: 731ms
  47. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()'. Took: 648ms
  48. Fetched 31465 objects using: 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)'. Took: 836ms
  49. Fetched 31465 objects using: 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)'. Took: 722ms
  50. Fetched 31465 objects using: 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)'. Took: 768ms
  51. Fetched 31465 objects using: 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)'. Took: 728ms
  52. Fetched 31465 objects using: 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)'. Took: 770ms
  53. Fetched 31465 objects using: 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)'. Took: 707ms
  54. Fetched 31465 objects using: 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)'. Took: 749ms
  55. Fetched 31465 objects using: 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)'. Took: 694ms
  56. Fetched 31465 objects using: 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)'. Took: 767ms
  57. Fetched 31465 objects using: 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)'. Took: 764ms
  58. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 971ms
  59. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 767ms
  60. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 728ms
  61. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 826ms
  62. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 775ms
  63. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 791ms
  64. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 808ms
  65. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 775ms
  66. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 853ms
  67. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 704ms
  68. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching'. Took: 1046ms
  69. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching'. Took: 395ms
  70. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching'. Took: 223ms
  71. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching'. Took: 232ms
  72. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching'. Took: 345ms
  73. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching'. Took: 328ms
  74. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching'. Took: 295ms
  75. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching'. Took: 296ms
  76. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching'. Took: 299ms
  77. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching'. Took: 302ms
  78. Fetched 31465 objects using: 'Dapper'. Took: 673ms
  79. Fetched 31465 objects using: 'Dapper'. Took: 601ms
  80. Fetched 31465 objects using: 'Dapper'. Took: 600ms
  81. Fetched 31465 objects using: 'Dapper'. Took: 615ms
  82. Fetched 31465 objects using: 'Dapper'. Took: 590ms
  83. Fetched 31465 objects using: 'Dapper'. Took: 599ms
  84. Fetched 31465 objects using: 'Dapper'. Took: 603ms
  85. Fetched 31465 objects using: 'Dapper'. Took: 598ms
  86. Fetched 31465 objects using: 'Dapper'. Took: 594ms
  87. Fetched 31465 objects using: 'Dapper'. Took: 576ms
  88. Fetched 31465 objects using: 'NHibernate v3.3.1.4000 (v3.3.3.4001)'. Took: 6980ms
  89. Fetched 31465 objects using: 'NHibernate v3.3.1.4000 (v3.3.3.4001)'. Took: 4838ms
  90. Fetched 31465 objects using: 'NHibernate v3.3.1.4000 (v3.3.3.4001)'. Took: 4651ms
  91. Fetched 31465 objects using: 'NHibernate v3.3.1.4000 (v3.3.3.4001)'. Took: 4432ms
  92. Fetched 31465 objects using: 'NHibernate v3.3.1.4000 (v3.3.3.4001)'. Took: 4577ms
  93. Fetched 31465 objects using: 'NHibernate v3.3.1.4000 (v3.3.3.4001)'. Took: 4580ms
  94. Fetched 31465 objects using: 'NHibernate v3.3.1.4000 (v3.3.3.4001)'. Took: 4662ms
  95. Fetched 31465 objects using: 'NHibernate v3.3.1.4000 (v3.3.3.4001)'. Took: 4552ms
  96. Fetched 31465 objects using: 'NHibernate v3.3.1.4000 (v3.3.3.4001)'. Took: 4539ms
  97. Fetched 31465 objects using: 'NHibernate v3.3.1.4000 (v3.3.3.4001)'. Took: 4681ms
  98. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 588ms
  99. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 581ms
  100. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 629ms
  101. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 570ms
  102. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 581ms
  103. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 585ms
  104. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 601ms
  105. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 585ms
  106. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 588ms
  107. Fetched 31465 objects using: 'DbDataReader, handcoded'. Took: 587ms
  108. Fetched 31465 objects using: 'DbDataAdapter into DataTable'. Took: 696ms
  109. Fetched 31465 objects using: 'DbDataAdapter into DataTable'. Took: 586ms
  110. Fetched 31465 objects using: 'DbDataAdapter into DataTable'. Took: 600ms
  111. Fetched 31465 objects using: 'DbDataAdapter into DataTable'. Took: 617ms
  112. Fetched 31465 objects using: 'DbDataAdapter into DataTable'. Took: 587ms
  113. Fetched 31465 objects using: 'DbDataAdapter into DataTable'. Took: 595ms
  114. Fetched 31465 objects using: 'DbDataAdapter into DataTable'. Took: 580ms
  115. Fetched 31465 objects using: 'DbDataAdapter into DataTable'. Took: 624ms
  116. Fetched 31465 objects using: 'DbDataAdapter into DataTable'. Took: 595ms
  117. Fetched 31465 objects using: 'DbDataAdapter into DataTable'. Took: 583ms
  118.  
  119. Individual entity fetch benches
  120. ------------------------------------------
  121. Fetching entities individually, LLBLGen Pro v4.1
  122. Fetched 31465 objects using: 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)'. Took: 759ms
  123. Fetching 1001 entities individually through CTor/PK fetch took 1757ms, or 1,75524475524476ms/entity
  124. Fetching entities individually, EF6.0.1
  125. Fetched 31465 objects using: 'Entity Framework v6.0.0.0 (v6.0.21010.0)'. Took: 3359ms
  126. Fetching 1001 entities individually through CTor/PK fetch took 3430ms, or 3,42657342657343ms/entity
  127.  
  128. Averaged total results per framework
  129. ------------------------------------------
  130. Average results of 'Entity Framework v6.0.0.0 (v6.0.21010.0)' is: 3470,22222222222ms
  131. Average results of 'Entity Framework v6.0.0.0 (v6.0.21010.0), using AsNoTracking()' is: 689,75ms
  132. Average results of 'Linq to Sql v4.0.0.0 (v4.0.30319.18408)' is: 746,875ms
  133. Average results of 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206)' is: 786,888888888889ms
  134. Average results of 'LLBLGen Pro v4.1.0.0 (v4.1.13.1206), with resultset caching' is: 311,5ms
  135. Average results of 'Dapper' is: 600ms
  136. Average results of 'NHibernate v3.3.1.4000 (v3.3.3.4001)' is: 4635ms
  137. Average results of 'DbDataReader, handcoded' is: 587ms
  138. Average results of 'DbDataAdapter into DataTable' is: 598,375ms
  139. Press any key to continue . . .
  140.  
  141. //--------------------------
  142. // Code used:
  143. using System;
  144. using System.Collections;
  145. using System.Collections.Generic;
  146. using System.Data;
  147. using System.Data.SqlClient;
  148. using System.Diagnostics;
  149. using System.Linq;
  150. using System.Text;
  151. using System.Threading.Tasks;
  152. using AdventureWorks.Dal.Adapter.v41.DatabaseSpecific;
  153. using AdventureWorks.Dal.Adapter.v41.EntityClasses;
  154. using AdventureWorks.Dal.Adapter.v41.HelperClasses;
  155. using AdventureWorks.Dal.Adapter.v41.FactoryClasses;
  156. using EF6.Bencher;
  157. using L2S.Bencher;
  158. using NH.Bencher;
  159. using NHibernate;
  160. using NHibernate.Linq;
  161. using Dapper;
  162. using SD.LLBLGen.Pro.QuerySpec;
  163. using SD.LLBLGen.Pro.QuerySpec.Adapter;
  164. using SD.LLBLGen.Pro.ORMSupportClasses;
  165. using System.Reflection;
  166.  
  167. namespace RawBencher
  168. {
  169.     class Program
  170.     {
  171.         private static Dictionary<string, List<long>> _rawResultsPerORM = new Dictionary<string, List<long>>();
  172.         private static string ConnectionString = @"data source=zeusVM\SQLSERVER2005;initial catalog=AdventureWorks;integrated security=SSPI;persist security info=False;packet size=4096";
  173.  
  174.         static void Main(string[] args)
  175.         {
  176.             CacheController.RegisterCache(ConnectionString, new ResultsetCache());
  177.             int loopAmount = 10;
  178.  
  179.             Console.WriteLine("\nWarming up DB, DB client code and CLR");
  180.             Console.WriteLine("------------------------------------------");
  181.             for(int i = 0; i < loopAmount; i++)
  182.             {
  183.                 FetchSalesOrderHeaderHandCoded();
  184.             }
  185.  
  186.             Console.WriteLine("\nStarting benchmarks");
  187.             Console.WriteLine("------------------------------------------");
  188.             _rawResultsPerORM.Clear();
  189.             for(int i = 0; i < loopAmount; i++)
  190.             {
  191.                 FetchSalesOrderHeaderEF();
  192.             }
  193.             for(int i = 0; i < loopAmount; i++)
  194.             {
  195.                 FetchSalesOrderHeaderEFNoTracking();
  196.             }
  197.             for(int i = 0; i < loopAmount; i++)
  198.             {
  199.                 FetchSalesOrderHeaderL2S();
  200.             }
  201.             for(int i = 0; i < loopAmount; i++)
  202.             {
  203.                 FetchSalesOrderHeaderEntities();
  204.             }
  205.             for(int i = 0; i < loopAmount; i++)
  206.             {
  207.                 FetchSalesOrderHeaderEntitiesWithCaching();
  208.             }
  209.             for(int i = 0; i < loopAmount; i++)
  210.             {
  211.                 FetchSalesOrderHeaderDapper();
  212.             }
  213.             for(int i = 0; i < loopAmount; i++)
  214.             {
  215.                 FetchSalesOrderHeaderNH();
  216.             }
  217.             for(int i = 0; i < loopAmount; i++)
  218.             {
  219.                 FetchSalesOrderHeaderHandCoded();
  220.             }
  221.             for(int i = 0; i < loopAmount; i++)
  222.             {
  223.                 FetchSalesOrderHeaderDataTable();
  224.             }
  225.  
  226.             Console.WriteLine("\nIndividual entity fetch benches");
  227.             Console.WriteLine("------------------------------------------");
  228.             FetchSalesOrderHeaderEntitiesIndividually();
  229.             FetchSalesOrderHeaderEFIndividually();
  230.  
  231.             Console.WriteLine("\nAveraged total results per framework");
  232.             Console.WriteLine("------------------------------------------");
  233.             CalculateFinalResultAverages();
  234.         }
  235.  
  236.  
  237.         private static void FetchSalesOrderHeaderDataTable()
  238.         {
  239.             var frameworkName = "DbDataAdapter into DataTable";
  240.             var sw = new Stopwatch();
  241.             sw.Start();
  242.             var headers = new DataTable();
  243.             using(var con = new SqlConnection(ConnectionString))
  244.             {
  245.                 var cmd = con.CreateCommand();
  246.                 cmd.CommandText = "select * from Sales.SalesOrderHeader";
  247.                 var adapter = new SqlDataAdapter(cmd);
  248.                 adapter.Fill(headers);
  249.             }
  250.             sw.Stop();
  251.             ReportResult(frameworkName, sw.ElapsedMilliseconds, headers.Rows.Count);
  252.  
  253.             for(int i = 0; i < headers.Rows.Count;i++ )
  254.             {
  255.                 if(Convert.ToInt32(headers.Rows[i]["SalesOrderID"]) <= 0)
  256.                 {
  257.                     Console.WriteLine("Data table: Data is empty");
  258.                     break;
  259.                 }
  260.             }
  261.         }
  262.  
  263.  
  264.         private static void FetchSalesOrderHeaderHandCoded()
  265.         {
  266.             var frameworkName = "DbDataReader, handcoded";
  267.  
  268.             var sw = new Stopwatch();
  269.             sw.Start();
  270.             var headers = new List<SalesOrderHeader>();
  271.             using(var con = new SqlConnection(ConnectionString))
  272.             {
  273.                 var cmd = con.CreateCommand();
  274.                 cmd.CommandText = "select * from Sales.SalesOrderHeader";
  275.                 con.Open();
  276.                 var reader = cmd.ExecuteReader();
  277.                 while(reader.Read())
  278.                 {
  279.                     object fieldValue = null;
  280.                     var soh = new SalesOrderHeader();
  281.                     soh.SalesOrderId = (int)reader.GetValue(0);
  282.                     soh.RevisionNumber = (byte)reader.GetValue(1);
  283.                     soh.OrderDate = (DateTime)reader.GetValue(2);
  284.                     soh.DueDate = (DateTime)reader.GetValue(3);
  285.                     fieldValue = reader.GetValue(4);
  286.                     soh.ShipDate = (DateTime)(fieldValue == DBNull.Value ? null : fieldValue);
  287.                     soh.Status = (byte)reader.GetValue(5);
  288.                     soh.OnlineOrderFlag = (bool)reader.GetValue(6);
  289.                     soh.SalesOrderNumber = (string)reader.GetValue(7);
  290.                     fieldValue = reader.GetValue(8);
  291.                     soh.PurchaseOrderNumber = (string)(fieldValue == DBNull.Value ? null : fieldValue);
  292.                     fieldValue = reader.GetValue(9);
  293.                     soh.AccountNumber = (string)(fieldValue == DBNull.Value ? null : fieldValue);
  294.                     soh.CustomerID = (int)reader.GetValue(10);
  295.                     soh.ContactID = (int)reader.GetValue(11);
  296.                     fieldValue = reader.GetValue(12);
  297.                     soh.SalesPersonID = (int?)(fieldValue == DBNull.Value ? null : fieldValue);
  298.                     fieldValue = reader.GetValue(13);
  299.                     soh.TerritoryID = (int?)(fieldValue == DBNull.Value ? null : fieldValue);
  300.                     soh.BillToAddressID = (int)reader.GetValue(14);
  301.                     soh.ShipToAddressID = (int)reader.GetValue(15);
  302.                     soh.ShipMethodID = (int)reader.GetValue(16);
  303.                     fieldValue = reader.GetValue(17);
  304.                     soh.CreditCardID = (int?)(fieldValue == DBNull.Value ? null : fieldValue);
  305.                     fieldValue = reader.GetValue(18);
  306.                     soh.CreditCardApprovalCode = (string)(fieldValue == DBNull.Value ? null : fieldValue);
  307.                     fieldValue = reader.GetValue(19);
  308.                     soh.CurrencyRateID = (int?)(fieldValue == DBNull.Value?null : fieldValue);
  309.                     soh.SubTotal = (decimal)reader.GetValue(20);
  310.                     soh.TaxAmt = (decimal)reader.GetValue(21);
  311.                     soh.Freight = (decimal)reader.GetValue(22);
  312.                     soh.TotalDue = (decimal)reader.GetValue(23);
  313.                     fieldValue = reader.GetValue(24);
  314.                     soh.Comment = (string)(fieldValue==DBNull.Value ? null : fieldValue);
  315.                     soh.Rowguid = (Guid)reader.GetValue(25);
  316.                     soh.ModifiedDate = (DateTime)reader.GetValue(26);
  317.                     headers.Add(soh);
  318.                 }
  319.                 reader.Close();
  320.                 con.Close();
  321.             }
  322.             sw.Stop();
  323.             ReportResult(frameworkName, sw.ElapsedMilliseconds, headers.Count);
  324.             foreach(var e in headers)
  325.             {
  326.                 if(e.SalesOrderId <= 0)
  327.                 {
  328.                     Console.WriteLine("Hand written: Data is empty");
  329.                     break;
  330.                 }
  331.             }
  332.         }
  333.  
  334.  
  335.         private static void FetchSalesOrderHeaderDapper()
  336.         {
  337.             var frameworkName = "Dapper";
  338.  
  339.             var sw = new Stopwatch();
  340.             sw.Start();
  341.             var headers = new List<SalesOrderHeader>();
  342.             using(var con = new SqlConnection(ConnectionString))
  343.             {
  344.                 con.Open();
  345.                 headers = con.Query<SalesOrderHeader>("select * from Sales.SalesOrderHeader").ToList();
  346.                 con.Close();
  347.             }
  348.             sw.Stop();
  349.             ReportResult(frameworkName, sw.ElapsedMilliseconds, headers.Count);
  350.  
  351.             foreach(var e in headers)
  352.             {
  353.                 if(e.SalesOrderId <= 0)
  354.                 {
  355.                     Console.WriteLine("Dapper: Data is empty");
  356.                     break;
  357.                 }
  358.             }
  359.         }
  360.  
  361.  
  362.         private static void FetchSalesOrderHeaderEntitiesWithCaching()
  363.         {
  364.             var frameworkName = CreateFrameworkName("LLBLGen Pro v{0} (v{1}), with resultset caching", typeof(DataAccessAdapterBase));
  365.             var sw = new Stopwatch();
  366.             sw.Start();
  367.             var qf = new QueryFactory();
  368.             var q = qf.SalesOrderHeader.CacheResultset(5);
  369.             var headers = new EntityCollection<SalesOrderHeaderEntity>();
  370.             using(var adapter = new DataAccessAdapter())
  371.             {
  372.                 adapter.FetchQuery(q, headers);
  373.             }
  374.             sw.Stop();
  375.             ReportResult(frameworkName, sw.ElapsedMilliseconds, headers.Count);
  376.             foreach(var e in headers)
  377.             {
  378.                 if(e.SalesOrderId <= 0)
  379.                 {
  380.                     Console.WriteLine("LLBL41 with cache: Data is empty");
  381.                     break;
  382.                 }
  383.             }
  384.         }
  385.  
  386.  
  387.         private static void FetchSalesOrderHeaderEntitiesIndividually()
  388.         {
  389.             Console.WriteLine("Fetching entities individually, LLBLGen Pro v4.1");
  390.             var headers = FetchSalesOrderHeaderEntities();
  391.             int count = 0;
  392.             var sw = new Stopwatch();
  393.             sw.Start();
  394.             foreach(var fetched in headers)
  395.             {
  396.                 var toFetch = new SalesOrderHeaderEntity(fetched.SalesOrderId);
  397.                 using(var adapter = new DataAccessAdapter())
  398.                 {
  399.                     adapter.FetchEntity(toFetch);
  400.                     if(toFetch.Fields.State != SD.LLBLGen.Pro.ORMSupportClasses.EntityState.Fetched)
  401.                     {
  402.                         Console.WriteLine("Not fetched. Aborting");
  403.                         return;
  404.                     }
  405.                     count++;
  406.                 }
  407.                 if(count > 1000)
  408.                 {
  409.                     break;
  410.                 }
  411.             }
  412.             sw.Stop();
  413.             double average = (double)sw.ElapsedMilliseconds / (double)count;
  414.             Console.WriteLine("Fetching {0} entities individually through CTor/PK fetch took {1}ms, or {2}ms/entity", count, sw.ElapsedMilliseconds, average);
  415.         }
  416.        
  417.  
  418.         private static EntityCollection<SalesOrderHeaderEntity> FetchSalesOrderHeaderEntities()
  419.         {
  420.             var frameworkName = CreateFrameworkName("LLBLGen Pro v{0} (v{1})", typeof(DataAccessAdapterBase));
  421.             var sw = new Stopwatch();
  422.             sw.Start();
  423.             var headers = new EntityCollection<SalesOrderHeaderEntity>();
  424.             using(var adapter = new DataAccessAdapter())
  425.             {
  426.                 adapter.FetchEntityCollection(headers, null);
  427.             }
  428.             sw.Stop();
  429.             ReportResult(frameworkName, sw.ElapsedMilliseconds, headers.Count);
  430.             foreach(var e in headers)
  431.             {
  432.                 if(e.SalesOrderId <= 0)
  433.                 {
  434.                     Console.WriteLine("LLBL41: Data is empty");
  435.                     break;
  436.                 }
  437.             }
  438.             return headers;
  439.         }
  440.  
  441.  
  442.         private static List<EF6.Bencher.EntityClasses.SalesOrderHeader>  FetchSalesOrderHeaderEF()
  443.         {
  444.             var frameworkName = CreateFrameworkName("Entity Framework v{0} (v{1})", typeof(System.Data.Entity.DbContext));
  445.             var sw = new Stopwatch();
  446.             sw.Start();
  447.             List<EF6.Bencher.EntityClasses.SalesOrderHeader> headers = null;
  448.             using(var ctx = new AWDataContext())
  449.             {
  450.                 headers = ctx.SalesOrderHeaders.ToList();
  451.             }
  452.             sw.Stop();
  453.             ReportResult(frameworkName, sw.ElapsedMilliseconds, headers.Count);
  454.             foreach(var e in headers)
  455.             {
  456.                 if(e.SalesOrderId <= 0)
  457.                 {
  458.                     Console.WriteLine("EF: Data is empty");
  459.                     break;
  460.                 }
  461.             }
  462.             return headers;
  463.         }
  464.  
  465.  
  466.         private static List<EF6.Bencher.EntityClasses.SalesOrderHeader> FetchSalesOrderHeaderEFNoTracking()
  467.         {
  468.             var frameworkName = CreateFrameworkName("Entity Framework v{0} (v{1}), using AsNoTracking()", typeof(System.Data.Entity.DbContext));
  469.             var sw = new Stopwatch();
  470.             sw.Start();
  471.             List<EF6.Bencher.EntityClasses.SalesOrderHeader> headers = null;
  472.             using(var ctx = new AWDataContext())
  473.             {
  474.                 headers = ctx.SalesOrderHeaders.AsNoTracking().ToList();
  475.             }
  476.             sw.Stop();
  477.             ReportResult(frameworkName, sw.ElapsedMilliseconds, headers.Count);
  478.             foreach(var e in headers)
  479.             {
  480.                 if(e.SalesOrderId <= 0)
  481.                 {
  482.                     Console.WriteLine("EF: Data is empty");
  483.                     break;
  484.                 }
  485.             }
  486.             return headers;
  487.         }
  488.  
  489.  
  490.         private static void FetchSalesOrderHeaderEFIndividually()
  491.         {
  492.             Console.WriteLine("Fetching entities individually, EF6.0.1");
  493.             var headers = FetchSalesOrderHeaderEF();
  494.             int count = 0;
  495.             var sw = new Stopwatch();
  496.             sw.Start();
  497.             foreach(var fetched in headers)
  498.             {
  499.                 using(var ctx = new AWDataContext())
  500.                 {
  501.                     var toFetch = ctx.SalesOrderHeaders.Single(soh => soh.SalesOrderId == fetched.SalesOrderId);
  502.                     count++;
  503.                 }
  504.                 if(count > 1000)
  505.                 {
  506.                     break;
  507.                 }
  508.             }
  509.             sw.Stop();
  510.             double average = (double)sw.ElapsedMilliseconds / (double)count;
  511.             Console.WriteLine("Fetching {0} entities individually through CTor/PK fetch took {1}ms, or {2}ms/entity", count, sw.ElapsedMilliseconds, average);
  512.         }
  513.  
  514.  
  515.         private static void FetchSalesOrderHeaderL2S()
  516.         {
  517.             var frameworkName = CreateFrameworkName("Linq to Sql v{0} (v{1})", typeof(System.Data.Linq.DataContext));
  518.             var sw = new Stopwatch();
  519.             sw.Start();
  520.             List<L2S.Bencher.EntityClasses.SalesOrderHeader> headers = null;
  521.             var ctx = new L2SBencherDataContext();
  522.             headers = ctx.SalesOrderHeaders.ToList();
  523.             sw.Stop();
  524.             ReportResult(frameworkName, sw.ElapsedMilliseconds, headers.Count);
  525.  
  526.             foreach(var e in headers)
  527.             {
  528.                 if(e.SalesOrderId <= 0)
  529.                 {
  530.                     Console.WriteLine("L2S: Data is empty");
  531.                     break;
  532.                 }
  533.             }
  534.         }
  535.  
  536.         private static void FetchSalesOrderHeaderNH()
  537.         {
  538.             var frameworkName = CreateFrameworkName("NHibernate v{0} (v{1})", typeof(ISession));
  539.             var sw = new Stopwatch();
  540.             sw.Start();
  541.             List<NH.Bencher.EntityClasses.SalesOrderHeader> headers = null;
  542.             using(var session = SessionManager.OpenSession())
  543.             {
  544.                 headers = session.Query<NH.Bencher.EntityClasses.SalesOrderHeader>().ToList();
  545.             }
  546.             sw.Stop();
  547.             ReportResult(frameworkName, sw.ElapsedMilliseconds, headers.Count);
  548.             foreach(var e in headers)
  549.             {
  550.                 if(e.SalesOrderId <= 0)
  551.                 {
  552.                     Console.WriteLine("NH: Data is empty");
  553.                     break;
  554.                 }
  555.             }
  556.         }
  557.  
  558.  
  559.         private static void GetVersionStrings(Assembly a, out string fileVersion, out string assemblyVersion)
  560.         {
  561.             fileVersion = string.Empty;
  562.             assemblyVersion = string.Empty;
  563.             if(a != null)
  564.             {
  565.                 assemblyVersion = a.GetName().Version.ToString();
  566.                 fileVersion = FileVersionInfo.GetVersionInfo(a.Location).FileVersion;
  567.             }
  568.         }
  569.  
  570.  
  571.         private static void ReportResult(string frameworkName, long elapsedTimeInMs, int amountFetched)
  572.         {
  573.             Console.WriteLine("Fetched {0} objects using: '{1}'. Took: {2}ms", amountFetched, frameworkName, elapsedTimeInMs);
  574.             List<long> container;
  575.             if(!_rawResultsPerORM.TryGetValue(frameworkName, out container))
  576.             {
  577.                 container = new List<long>();
  578.                 _rawResultsPerORM.Add(frameworkName, container);
  579.             }
  580.             container.Add(elapsedTimeInMs);
  581.         }
  582.  
  583.  
  584.         private static string CreateFrameworkName(string formatString, Type t)
  585.         {
  586.             string assemblyVersion;
  587.             string fileVersion;
  588.             GetVersionStrings(t.Assembly, out fileVersion, out assemblyVersion);
  589.             return string.Format(formatString, assemblyVersion, fileVersion);
  590.         }
  591.  
  592.  
  593.         private static void CalculateFinalResultAverages()
  594.         {
  595.             foreach(var kvp in _rawResultsPerORM)
  596.             {
  597.                 var results = kvp.Value;
  598.                 if(results.Count<=2)
  599.                 {
  600.                     Console.WriteLine("Not enough results: '{0}'", kvp.Key);
  601.                     continue;
  602.                 }
  603.  
  604.                 // ignore slowest and fastest result, then calculate the average.
  605.                 results.Sort();
  606.                 long total = 0;
  607.                 for(int i = 1; i < results.Count - 1; i++)
  608.                 {
  609.                     total += results[i];
  610.  
  611.                 }
  612.                 // safe, 2 or less results are not accepted as we have to skip fastest and slowest.
  613.                 var average = (double)total/(double)(results.Count-2);
  614.                 Console.WriteLine("Average results of '{0}' is: {1}ms", kvp.Key, average);
  615.             }
  616.         }
  617.     }
  618. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement