1. 程式人生 > >使用 BenchmarkDotnet 測試程式碼效能

使用 BenchmarkDotnet 測試程式碼效能

原文: 使用 BenchmarkDotnet 測試程式碼效能

先來點題外話,清明節前把工作辭了(去 tm 的垃圾團隊,各種拉幫結派、勾心鬥角)。這次找工作就得慢慢找了,不能急了,希望能找到個好團隊,好崗位吧。順便這段時間也算是比較閒,也能學習一下和填掉手上的坑。

說實話好久沒寫部落格了,一個是手上的工作確實忙,第二個是還有各種各樣的坑。寫本文的原因也是因為手上的一個坑——ImageEx,WPF/UWP 上的圖片快取控制元件。

 

在我寫的這個圖片快取控制元件中,其中有一個地方就是要根據圖片的 url 地址,然後來儲存或者獲取本地的圖片檔案的。但是呢,我們不可能把 url 當作本地檔案的檔名的,一個是可能包含非法字元(如斜槓),另一個是長度可能超出限制。想了一下,那就只能用雜湊(hash)來解決了,其中 MD5 和 SHA1 兩種演算法我覺得都可以解決這個問題。但問題是,哪一個更好、更快呢?傳統經驗告訴我是 MD5,但是我覺得還是有必要手動實踐一下,畢竟沒有 100% 的把握。

先編寫出如下的程式碼:

public static class HashHelper
{
    public static string GetMD5(string input)
    {
        if (input == null)
        {
            throw new ArgumentNullException(nameof(input));
        }

        using (var md5 = MD5.Create())
        {
            var buffer = Encoding.UTF8.GetBytes(input);
            
var hashResult = md5.ComputeHash(buffer); return BitConverter.ToString(hashResult).Replace("-", string.Empty); } } public static string GetSHA1(string input) { if (input == null) { throw new ArgumentNullException(nameof(input)); }
using (var sha1 = SHA1.Create()) { var buffer = Encoding.UTF8.GetBytes(input); var hashResult = sha1.ComputeHash(buffer); return BitConverter.ToString(hashResult).Replace("-", string.Empty); } } }

作用是輸入一個字串,輸出一個雜湊後的字串。

 

建立一個 .net core 的控制檯專案,我就叫 TestBenchmarkDotnet。

然後安裝 nuget 包,BenchmarkDotnet。

QQ截圖20180408222314

安裝完成後編寫如下程式碼:

public class TestContext
{
    [Benchmark]
    public void TestMD5()
    {
        HashHelper.GetMD5("https://www.baidu.com/img/bd_logo1.png");
    }

    [Benchmark]
    public void TestSHA1()
    {
        HashHelper.GetSHA1("https://www.baidu.com/img/bd_logo1.png");
    }
}

然後修改 Main 方法:

public class Program
{
    public static void Main(string[] args)
    {
        Summary summary = BenchmarkRunner.Run<TestContext>();
        Console.ReadLine();
    }
}

最後將 Debug 調成 Release 模式,不除錯啟動。

稍微等待一會兒就會出現結果了。

QQ截圖20180408223415

結論是 MD5 確實比 SHA1 快。

另外由於這是在 .net core 下的測試結果,而 WPF 是跑在 .net framework 下的,那麼是否結果可能不一樣呢?

Benchmark 支援多個 .net 環境的效能測試(.net framework, net core, mono)。

修改 TestContext 類的程式碼:

[ClrJob, CoreJob]
public class TestContext
{
    [Benchmark]
    public void TestMD5()
    {
        HashHelper.GetMD5("https://www.baidu.com/img/bd_logo1.png");
    }

    [Benchmark]
    public void TestSHA1()
    {
        HashHelper.GetSHA1("https://www.baidu.com/img/bd_logo1.png");
    }
}

添加了 ClrJob 和 CoreJob 兩個標籤

然後修改專案的 csproj 檔案

<TargetFramework>netcoreapp2.0</TargetFramework>

一行改為

<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>

回到 VS 重新編譯,還原 nuget 包。

不除錯啟動。稍等片刻。

QQ截圖20180408230358

可見在 .net framework 環境下,仍然是 MD5 比 SHA1 快的。而且可以看見 .net core 比 .net framework 環境下快了很多。

另外在輸出目錄下,BenchmarkDotnet 會輸出效能測試結果檔案:

QQ截圖20180408230657

開啟 html 版本後看到的跟剛才控制檯的是一樣的

QQ截圖20180408230743