.NET Core 性能分析: xUnit.Performance 简介
?xunit-performance 是xUnit的一個擴展, 使用它可以對.NET Core項目進行性能測試。
官網:https://github.com/Microsoft/xunit-performance
?
xUnit大家可能都用過,它是用來做單元測試的,它可以很快給開發人員功能是否OK的反饋。
和xUnit一樣,xUnit-Performance可以很快給出性能上的反饋。
?
準備和安裝xUnit-Performance
為了講解,我們需要準備一個需要被測試的項目和一個測試項目。
我使用Visual Studio 2017建立項目之后總有一些問題,不過后來我是用dotnet cli和VSCode就沒有什么問題了。
?
建立項目的順序如下:
1. 首先使用dotnet cli建立一個classlib類型的被測試項目,它的目標框架是.NET Standard 2.0:
?
這個項目里只有一個類,也就是要被測試的類:
這個類有三個方法,分別是使用foreach,for和Linq擴展方法的Sum對集合循環并求和。
?
2. 使用dotnet cli建立一個console項目(如果使用VS2017的話直接建類庫就可以,因為VS2017內置Test Runner),這個是測試項目,它的版本只能是2.0(可能是因為我電腦sdk的版本較老):
另外還需要引用被測試項目。
?
3.然后,按照官方文檔安裝兩個庫。?
xUnit-Performance目前還處于Beta階段,這兩個庫需要按照官網的指示進行安裝:
最新版的xunit.performance.api.dll, 這里用到的是MyGet:??https://dotnet.myget.org/feed/dotnet-core/package/nuget/xunit.performance.api#.
?
然后是最新版的?Microsoft.Diagnostics.Tracing.TraceEvent, 這個使用Nuge:?https://www.nuget.org/packages/Microsoft.Diagnostics.Tracing.TraceEvent
?
OK,現在依賴庫都裝好了。
?
編寫性能測試
性能測試和單元測試略有不同, 性能測試是跑很多次, 然后取平均值. 同時也要考慮到內存等其它因素的影響.
在性能測試里就不需要測試功能的正確性了, 但是程序在壓力下可能會產生不同的結果, 尤其是多線程的情況. 這時你就需要寫壓力測試了.
而對于性能測試, 我們只考慮速度.
?
由于我是用的是dotnet cli和VSCode,所以測試項目我選用的是控制臺項目,它的Main方法需要這樣寫:
如果您能成功的使用VS2017建立測試項目,那么就不需要Main方法了,建立一個類庫項目即可,直接使用VS2017的Test Runner即可。
?
性能測試代碼
下面我們編寫性能測試方法。
首先在測試項目建立一個類,然后做一些準備工作:
這里我準備了一個List<KeyValuePair<int, double>>,它有100000條數據,是隨機生成的。
?
然后是測試方法,在這里我們使用[Benchmark]替代了xUnit單元測試中的[Fact]:
xUnit.Performance的測試會跑很多次,結果是取平均值的。
這里我們循環遍歷Benchmark.Iterations,它有一個默認值,我這里默認是跑了1000次循環。
再循環里,首先您可以做一些準備工作。然后使用iteration.StartMeasurement()來開始進行測量。
只有iteration.StartMeasurement()后邊的部分才會被測量,在大括號里面寫被測試相關的代碼就可以了。
?
然后在命令行輸入運行測試:
dotnet run --perf:collect stopwatch
?
測試結果如下:
提供了控制臺輸出,xml,csv,md輸出(在項目文件夾里)。
從控制臺可以看到該測試的循環跑了1000次,平均結果是0.963毫秒。
?
下面是csv結果的截圖:
?
下面是md結果文件的截圖:
?
下面是xml結果文件的截圖,它里面有詳細數據:
?
內部循環
xUnit.Performance還可以添加一個內部循環屬性?InnerIterationCount。先看代碼,添加以下方法:
[Benchmark(InnerIterationCount = 10_000)],這里的InnerIterationCount是內部循環遍歷的次數。
在StartMeasurement()之后,進行內部循環。
這樣的話,外層循環的次數可能會很少,而且第一次外層循環是熱身,不包括在測試結果中。
而內部循環適合于運行比較快速的代碼(微秒級)。
?
有時確實需要這樣兩層循環,做一些熱身工作或者需要完成不同級別的準備工作。
?
然后我們來跑測試
在結果里看到外層循環有2次的記錄,但是它實際跑了3次,第一次算作熱身,不做統計。
它的時間是內層循環的總和,除以10000之后,和第一個方法的結果差不太多。
?
我可以在方法中打印輸出循環次數:
其結果如下:
可以看到確實是跑了3次,但統計了2次。
?
然后我再添加另外兩個測試方法,分別測試另外兩個方法:
?
運行測試:
可以看到現在這4個測試方法的結果。
看來針對List來說foreach要比linq和for循環快。
注意foreach測試的外層循環跑了2次,而for和linq的測試循環只跑了1次,可能是因為花費時間太久了吧?這個我不太確定。
?
StopWatch
可以看到測試命令的參數 stopwatch,它應該是來自System.Diagnostics命名空間下的StopWatch類。
它有Start()和Stop()方法和一些其它屬性用來統計逝去的時間。
StopWatch類是跨平臺的,但是在其它系統上,它只能統計時間;而在Windows上,它還可以使用內核ETW events和CPU性能計數來給您更多的數據,具體請查閱相關資料。
?
結語
該庫還有很多功能和命令的參數,具體請參考文檔:https://github.com/Microsoft/xunit-performance
但是要注意,它仍然是beta狀態,只能在MyGet而不是Nuget獲取。
博客文章可以隨便轉載和抓取.?
總結
以上是生活随笔為你收集整理的.NET Core 性能分析: xUnit.Performance 简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Insider Dev Tour 201
- 下一篇: TeamCity+Rancher+Doc