我打算回答你的問題的第三部分,因爲我已經多次取得了一些成功。
當性能是 關鍵要求時,您將如何應用red-> green-> refactor?
- 寫釘扎測試,以趕上回歸,對於計劃更改,並且可能會減慢爲你改變的結果的其他方法是什麼。
- 編寫失敗的性能測試。
- 提高性能,頻繁運行所有測試。
- 更新您的釘扎測試,以更貼近的性能。
寫牽制測試
創建的helper方法像這樣要固定的時間。
private TimeSpan Time(Action toTime)
{
var timer = Stopwatch.StartNew();
toTime();
timer.Stop();
return timer.Elapsed;
}
然後寫一個測試,斷言你的方法沒有任何時間:
[Test]
public void FooPerformance_Pin()
{
Assert.That(Time(()=>fooer.Foo()), Is.LessThanOrEqualTo(TimeSpan.FromSeconds(0));
}
當它失敗(在失敗的消息所經過的實際時間),更新的東西比略多的時間實際時間。重新運行,它會通過。對其他可能影響您的更改的功能重複執行此操作,最終得到類似的結果。
[Test]
public void FooPerformance_Pin()
{
Assert.That(Time(()=>fooer.Foo()), Is.LessThanOrEqualTo(TimeSpan.FromSeconds(0.8));
}
[Test]
public void BarPerformance_Pin()
{
Assert.That(Time(()=>fooer.Bar()), Is.LessThanOrEqualTo(TimeSpan.FromSeconds(6));
}
寫一個失敗的性能測試
我喜歡稱這種測試的「引誘測試」。這只是釘扎測試的第一步。
[Test]
public void FooPerformance_Bait()
{
Assert.That(Time(()=>fooer.Foo()), Is.LessThanOrEqualTo(TimeSpan.FromSeconds(0));
}
現在,在性能改進上工作。在每次試驗性改進後運行所有測試(固定和誘餌)。如果成功,您會看到誘餌測試的失敗輸出中的時間會減少,並且您的任何固定測試都不會失敗。
當您對改進感到滿意時,請更新您更改的代碼的固定測試,並刪除誘餌測試。
你現在對這些測試做什麼?
最簡單的做法是用Explicit屬性標記這些測試,並在下次希望檢查性能時保留它們。
在工作範圍的另一面,在CI中創建一個合理控制良好的子系統來運行這些測試是監控績效迴歸的一個非常好的方法。根據我的經驗,很多人擔心他們「因其他的CPU負載而隨機失敗」,而不是真正的失敗。這種努力的成功與否取決於團隊文化,而不是您對環境的控制能力。
執行的指令數量不一定等於性能。爲什麼在這裏不是時鐘的關鍵指標呢? – 2013-03-03 01:13:12
同意 - 但如果爲了響應特定的一組輸入而執行的指令數量因代碼修改而發生顯着變化,我想知道這一點。這就是我要找的東西。 – 2013-03-03 01:14:35
我不會使用單元測試來驗證。如果開發人員正在改變工作方式,完成高度優化的代碼,那麼他們應該確切地知道他們在做什麼。這段代碼不太可能需要進行'調整'嗎?那爲什麼要麻煩?性能是一個非功能性特徵。 – 2013-03-03 01:14:45