『性能』測試一下 MSSqlHelper 的性能

来源:https://www.cnblogs.com/shuxiaolong/archive/2018/07/22/20180722_0147.html
-Advertisement-
Play Games

本文沒啥技術含量,就是測試一下 MSSqlHelper 在 使用反射、不使用反射 的性能對比。 之後,不要問為什麼不用 ORM 這類的東西 —— 會有另外的文章 介紹 自己這些年 自己的ORM 升級歷史。 背景: 我自己有一個 MSSqlHelper, 這個 輔助類 是最基本的一個 資料庫操作類。 ...


本文沒啥技術含量,就是測試一下 MSSqlHelper 在 使用反射、不使用反射 的性能對比。

之後,不要問為什麼不用 ORM 這類的東西 —— 會有另外的文章 介紹 自己這些年 自己的ORM 升級歷史。

 

背景:

我自己有一個 MSSqlHelper, 這個 輔助類  是最基本的一個 資料庫操作類。

Query 查詢集合時,可以指定  reader => 對象  的委托 —— 如果不指定,則 MSSqlHelper 會自動通過反射賦值。

 

        static void Main(string[] args)
        {
            Test0();
            Test1();


            Test0();
            Test1();

            Console.ReadKey();
        }

        public static void Test0()
        {
            string connString = "Data Source=localhost;Initial Catalog=InkFxBlog;User Id=sa; Pwd=123.com;";
            DateTime time0 = DateTime.Now;
            List<TS_SDK> list = MSSqlHelper.Query<TS_SDK>(connString, "SELECT * FROM dbo.TS_SDK");
            DateTime time1 = DateTime.Now;
            Console.WriteLine("Test0 | " + list.Count + " | " + (time1 - time0).TotalSeconds + "秒");
        }

        public static void Test1()
        {
            string connString = "Data Source=localhost;Initial Catalog=InkFxBlog;User Id=sa; Pwd=123.com;";
            DateTime time0 = DateTime.Now;
            List<TS_SDK> list = MSSqlHelper.Query<TS_SDK>(connString, "SELECT * FROM dbo.TS_SDK", null, reader =>
            {
                TS_SDK item = new TS_SDK();
                item.FId = (Int64)reader["FId"]; 
                item.FNumber = (string)reader["FNumber"]; 
                item.FEnum = (string)reader["FEnum"]; 
                item.FName = (string)reader["FName"]; 
                item.FSDKName = (string)reader["FSDKName"]; 
                item.FFullName = (string)reader["FFullName"]; 
                item.FType = (string)reader["FType"];
                item.FVisit = (string)reader["FVisit"]; 
                item.FInheritFrom = (string)reader["FInheritFrom"]; 
                item.FJoinBaseType = (string)reader["FJoinBaseType"];
                item.FJoinChildType = (string)reader["FJoinChildType"]; 
                item.FIsStatic = (Boolean)reader["FIsStatic"]; 
                item.FIsOverride = (Boolean)reader["FIsOverride"]; 
                item.FIsVirtual = (Boolean)reader["FIsVirtual"]; 
                item.FIsAbstract = (Boolean)reader["FIsAbstract"]; 
                item.FIsInherit = (Boolean)reader["FIsInherit"]; 
                item.FIsNetFx = (Boolean)reader["FIsNetFx"]; 
                item.FOutUrl = (string)reader["FOutUrl"]; 
                item.FSummary = (string)reader["FSummary"]; 
                item.FRtSummary = (string)reader["FRtSummary"];
                item.FCSCode = (string)reader["FCSCode"]; 
                item.FVBCode = (string)reader["FVBCode"]; 
                item.FCPPCode = (string)reader["FCPPCode"]; 
                item.FFSCode = (string)reader["FFSCode"]; 
                item.FAssembly = (string)reader["FAssembly"];
                item.FVersion = (string)reader["FVersion"]; 
                item.FNameSpace = (string)reader["FNameSpace"]; 
                item.FParentId = (Int64)reader["FParentId"]; 
                item.FParentNumber = (string)reader["FParentNumber"];
                item.FDemo = (string)reader["FDemo"]; 
                item.FInfo = (string)reader["FInfo"]; 
                return item;
            });
            DateTime time1 = DateTime.Now;
            Console.WriteLine("Test1 | " + list.Count + " | " + (time1 - time0).TotalSeconds + "秒");
        }

  

運行結果:

 

讀取了全表 7W行記錄。

—— 很明顯:沒有指定 reader 讀取的委托、使用內置的反射代碼 足足慢了 3秒。

—— 當然,MSSqlHelper 內置的委托 進行了穩定性控制,使用了 這類代碼:

item.FId = Tools.ToLong(reader["FId"]);
item.FName = Tools.ToString("FName");

 這類轉換函數,性能肯定沒有 下麵的代碼 性能快:

item.FId = (Int64)reader["FId"]; 
item.FName = (string)reader["FName"];

 

我為什麼死活堅持 Tools 提供的 類型強轉?

> 因為穩定

> 轉換範圍廣 : 相容下麵這類 變態資料庫數據 

//這是 瀏覽器的 時間格式,以下代碼 能得到 2017-03-20 02:46:06 000
DateTime timeA = Tools.ToDateTime("Mon Mar 20 2017 02:46:06 GMT+0800 (中國標準時間)");  

//以下代碼 能得到 2017-03-19 01:43:15 000
DateTime timeA = Tools.ToDateTime("2017年3月19日 01時43分15秒");  

  

 

我們再使用 Tools 的類型強轉函數 試一試,看一下 Tools 的類型轉換會浪費多少性能

        public static void Test2()
        {
            string connString = "Data Source=localhost;Initial Catalog=InkFxBlog;User Id=sa; Pwd=123.com;";
            DateTime time0 = DateTime.Now;
            List<TS_SDK> list = MSSqlHelper.Query<TS_SDK>(connString, "SELECT * FROM dbo.TS_SDK", null, reader =>
            {
                TS_SDK item = new TS_SDK();

                //這次的 reader 委托, 
                //類型轉換 使用的 Tools.ToLong() Tools.ToLong() 這類函數
                //為什麼不直接用 (string)reader["FName"] 這類直接轉換 ? —— 為了穩定性、我寧願犧牲性能


                item.FId = Tools.ToLong(reader["FId"]);
                item.FNumber = Tools.ToString(reader["FNumber"]);
                item.FEnum = Tools.ToString(reader["FEnum"]);
                item.FName = Tools.ToString(reader["FName"]);
                item.FSDKName = Tools.ToString(reader["FSDKName"]);
                item.FFullName = Tools.ToString(reader["FFullName"]);
                item.FType = Tools.ToString(reader["FType"]);
                item.FVisit = Tools.ToString(reader["FVisit"]);
                item.FInheritFrom = Tools.ToString(reader["FInheritFrom"]);
                item.FJoinBaseType = Tools.ToString(reader["FJoinBaseType"]);
                item.FJoinChildType = Tools.ToString(reader["FJoinChildType"]);
                item.FIsStatic = Tools.ToBoolean(reader["FIsStatic"]);
                item.FIsOverride = Tools.ToBoolean(reader["FIsOverride"]);
                item.FIsVirtual = Tools.ToBoolean(reader["FIsVirtual"]);
                item.FIsAbstract = Tools.ToBoolean(reader["FIsAbstract"]);
                item.FIsInherit = Tools.ToBoolean(reader["FIsInherit"]);
                item.FIsNetFx = Tools.ToBoolean(reader["FIsNetFx"]);
                item.FOutUrl = Tools.ToString(reader["FOutUrl"]);
                item.FSummary = Tools.ToString(reader["FSummary"]);
                item.FRtSummary = Tools.ToString(reader["FRtSummary"]);
                item.FCSCode = Tools.ToString(reader["FCSCode"]);
                item.FVBCode = Tools.ToString(reader["FVBCode"]);
                item.FCPPCode = Tools.ToString(reader["FCPPCode"]);
                item.FFSCode = Tools.ToString(reader["FFSCode"]);
                item.FAssembly = Tools.ToString(reader["FAssembly"]);
                item.FVersion = Tools.ToString(reader["FVersion"]);
                item.FNameSpace = Tools.ToString(reader["FNameSpace"]);
                item.FParentId = Tools.ToLong(reader["FParentId"]);
                item.FParentNumber = Tools.ToString(reader["FParentNumber"]);
                item.FDemo = Tools.ToString(reader["FDemo"]);
                item.FInfo = Tools.ToString(reader["FInfo"]);
                return item;
            });
            DateTime time1 = DateTime.Now;
            Console.WriteLine("Test2 | " + list.Count + " | " + (time1 - time0).TotalSeconds + "秒");
        }

  

再測試一下:

 

—— 近期想把自己的底層輔助類 再優化一下,所以把代碼翻出來,折騰一下 ~

 

 

----------------------------------------------------------------------------------------------------------------------------------------

剛剛修改了一下 反射的代碼,啟用了 Emit 高速反射

性能果然得到了 明顯提升,性能僅損失 15 ~20%  —— 我已經知足了。

Ps. 目前的 Emit反射 使用的通用代碼(內外一個輔助類) —— 如果針對性的寫 Emit 代碼,性能還能再次提升,但我懶得寫。

 

 

----------------------------------------------------------------------------------------------------------------------------------------

 

增加了一個 最原生寫法 —— 也就是 性能極限

        public static void TestSouce()
        {
            string connString = "Data Source=localhost;Initial Catalog=InkFxBlog;User Id=sa; Pwd=123.com;";
            DateTime time0 = DateTime.Now;

            List<TS_SDK> list =new List<TS_SDK>();
            using (SqlConnection conn = new SqlConnection(connString))
            {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "SELECT * FROM dbo.TS_SDK";
                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            TS_SDK item = new TS_SDK();
                            item.FId = (Int64)reader["FId"];
                            item.FNumber = (string)reader["FNumber"];
                            item.FEnum = (string)reader["FEnum"];
                            item.FName = (string)reader["FName"];
                            item.FSDKName = (string)reader["FSDKName"];
                            item.FFullName = (string)reader["FFullName"];
                            item.FType = (string)reader["FType"];
                            item.FVisit = (string)reader["FVisit"];
                            item.FInheritFrom = (string)reader["FInheritFrom"];
                            item.FJoinBaseType = (string)reader["FJoinBaseType"];
                            item.FJoinChildType = (string)reader["FJoinChildType"];
                            item.FIsStatic = (Boolean)reader["FIsStatic"];
                            item.FIsOverride = (Boolean)reader["FIsOverride"];
                            item.FIsVirtual = (Boolean)reader["FIsVirtual"];
                            item.FIsAbstract = (Boolean)reader["FIsAbstract"];
                            item.FIsInherit = (Boolean)reader["FIsInherit"];
                            item.FIsNetFx = (Boolean)reader["FIsNetFx"];
                            item.FOutUrl = (string)reader["FOutUrl"];
                            item.FSummary = (string)reader["FSummary"];
                            item.FRtSummary = (string)reader["FRtSummary"];
                            item.FCSCode = (string)reader["FCSCode"];
                            item.FVBCode = (string)reader["FVBCode"];
                            item.FCPPCode = (string)reader["FCPPCode"];
                            item.FFSCode = (string)reader["FFSCode"];
                            item.FAssembly = (string)reader["FAssembly"];
                            item.FVersion = (string)reader["FVersion"];
                            item.FNameSpace = (string)reader["FNameSpace"];
                            item.FParentId = (Int64)reader["FParentId"];
                            item.FParentNumber = (string)reader["FParentNumber"];
                            item.FDemo = (string)reader["FDemo"];
                            item.FInfo = (string)reader["FInfo"];
                            list.Add(item);
                        }
                    }
                }
            }

            DateTime time1 = DateTime.Now;
            Console.WriteLine("TestSouce | " + list.Count + " | " + (time1 - time0).TotalSeconds + "秒");
        }

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 大道至簡這本書總體來說比較通俗易懂,同時在說明自己觀點的時候引用了許多古代的例子,更加的形象生動有趣,可讀性很強。 前幾章的主要思想如下: 程式=演算法+結構+方法;編程的第一要務是先把事情分析清楚,把事件先後的邏輯關係和依賴關係搞清楚,然後再去寫代碼實現。代碼是不存在的,存在的只是思想。其實演算法是對 ...
  • 一、多進程 1.1 多進程的概念 由於GIL的存在,python中的多線程其實並不是真正的多線程,如果想要充分地使用多核CPU的資源,在python中大部分情況需要使用多進程。Python提供了非常好用的多進程包multiprocessing,只需要定義一個函數,Python會完成其他所有事情。藉助 ...
  • 今天和大家聊聊golang中怎麼使用rpc,rpc數據傳輸會涉及到gob編碼,所以先講講gob,別擔心,就算你完全沒有接觸過gob與rpc,只要知道rpc的中文是遠程過程調用,剩下的我都能給你講明白(帶你入門不包你精通)! 一、數據結構編碼之gob gob全稱為:Go binary Golang自帶 ...
  • Mysqli面向對象操作資料庫 首先配置一下資料庫: 接著用PHP中的Mysqli擴展庫面向對象查詢這個數據表。 操作分為以下幾個步驟: 連接資料庫 操作資料庫 處理結果 關閉資源 query($sql); //查詢語句返回結果集 while($row=$result fetch_row()){ f ...
  • 1、JDBC:JDBA是Java資料庫連接(Java DataBase Connectivity)技術的簡稱,提供連接各種常用資料庫的能力; ●Java是通過JDBC技術實現對各種資料庫訪問的, ●JDBA是Java資料庫連接(Java DataBase Connectivity)技術的簡稱,他充當 ...
  • 1. 什麼是函數 2. 函數的定義及調用 進群:125240963 即可獲取數十套PDF哦! 2.1 定義函數 函數定義規則如下: 2.2 函數中的參數 參數的作用 函數,把具有獨立功能的代碼塊組織成為一個小模塊,在需要的時候調用 函數的參數,增加函數的通用性,針對相同的數據處理邏輯,能夠適應更多的 ...
  • "DotNet菜園" 占個位置 ...
  • 0.使用說明 AliDDNSNet 是基於 .NET Core 開發的動態 DNS 解析工具,藉助於阿裡雲的 DNS API 來實現功能變數名稱與動態 IP 的綁定功能。 使用時請更改同目錄下的 為 文件,同時也可以顯示通過 參數來制定配置文件路徑。例如: 1.配置說明: 通過更改 / 的內容來實現 DDN ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...