2009-04-15 69 views
8

我正在研究一個嚴重需要性能調整的項目。執行TDD時的性能測試最佳實踐?

我怎樣寫一個測試,如果我的優化不會在提高程序的速度不成?

要詳細一點:

的問題是不是發現優化哪些部分。我可以使用各種分析和基準測試工具。

問題是使用自動化測試證明特定的優化確實具有預期的效果。如果我能夠使用測試套件發現後續的可能的性能迴歸,那也是非常理想的。

我想我可以只運行我的分析工具得到一些值,然後斷言,我的優化代碼產生更好的價值。但是,顯而易見的問題是基準價值並不是硬性價值。它們因當地環境而異。

那麼,答案始終使用同一臺機器做這種集成測試的?如果是這樣,您仍然必須考慮結果中的模糊性,因爲即使在相同的硬件上,基準測試結果也可能會有所不同。那麼如何考慮這一點呢?

或者,也許答案是保留舊版本的程序和前後對比效果?這將是我首選的方法,因爲它主要是環境不可知的。有沒有人有這種方法的經驗?我想如果所有測試都可以通過,如果最新版本的性能至少與前一版本一樣好,那麼只需要保留一個較舊的版本。

回答

3

首先,你需要建立一些標準,可接受的性能,那麼你需要制定一個測試使用現有的代碼時,將不能在該標準,那麼你就需要調整你的代碼的性能,直到它通過了測試。你可能會有不止一個表現標準,你應該有一個以上的測試。

+0

您是否將此斷言提交給修訂控制?你是否期望它被檢出在多種類型的機器上?如果是這樣(就像我想象的那樣),你如何提供任何合理的期望,你的斷言適用於更慢/更快的機器? – bukzor 2013-10-30 20:53:37

2

記錄當前代碼的運行時間。

if (newCode.RunningTime >= oldCode.RunningTime) Fail 
+1

即使在最乖的系統中,這也會產生假陽性(當一切都很好時失敗)50%的時間;這是一個無法解決的問題。 「 – bukzor 2013-10-30 20:49:03

3

在許多服務器應用程序(可能不是您的情況)中,性能問題僅在併發訪問和負載下出現。因此,測量例程執行的絕對時間並嘗試改進它,因此不是很有幫助。即使在單線程應用程序中,該方法也存在問題。測量絕對例行時間依賴於平臺提供的時鐘,這些是not always very precise;你最好依靠例行的平均時間。

我的建議是:

  • 使用概要分析來確定執行次數最多的和最需要時例程。
  • JMeterGrinder使用的工具來闡述代表性的測試案例,模擬併發訪問,把下壓力和措施(更重要的)的吞吐量和平均響應時間您的應用程序。這將使您更好地瞭解您的應用程序如何從外部角度看待其行爲。

儘管您可以使用單元測試來確定應用程序的某些非功能性方面,但我認爲上述方法將在優化過程中給出更好的結果。在單元測試中放置與時間相關的斷言時,您必須選擇一些非常接近的值:時間可能因您用於運行單元測試的環境而異。你不想讓測試失敗,只是因爲你的一些同事使用劣質硬件。

調整是關於尋找合適的東西來調整。您已經擁有了一個功能正常的代碼,因此將性能相關的斷言後續並且沒有建立關鍵代碼段可能會導致您浪費大量的時間來優化應用程序的非關鍵部分。

+0

」時間可能會因您運行單元測試的環境而有所不同,您不希望測試失敗的原因僅在於您的某些同事使用劣質硬件。「 這非常正確,部分原因是我的頭痛。 – KaptajnKold 2009-04-16 09:15:56

+0

調整完系統後,如何防止它退化?在所有其他軟件迴歸場景中,解決方案是向測試套件添加一個斷言。 – bukzor 2013-10-30 20:53:05

1

在CI服務器上運行測試+分析。您也可以定期運行負載測試。

你擔心差異(正如你所提到的),所以它不是關於定義絕對值。有一個額外的步驟,將本次運行的性能度量與上一次構建的性能度量進行比較,並將差異報告爲%。你可以爲重要的時間變化提高紅旗。

如果你關心績效,你應該有明確的目標,你想要見面和斷言他們。您應該在整個系統上測試這些測試。即使您的應用程序邏輯速度很快,您可能會在視圖中遇到問題,導致您錯過目標。你也可以將它與差異方法結合起來,但對於這些方法,你對時間變化的容忍度會更低。

請注意,您可以在您的開發計算機中運行相同的過程,僅使用該計算機中的先前運行,而不是開發人員之間共享的過程。

5

我懷疑應用TDD來提升性能是一個錯誤。通過一切手段,使用它來獲得良好的設計和工作代碼,並使用在TDD過程中編寫的測試來確保持續的正確性 - 但是一旦您擁有良好的代碼和一套完整的測試,您就會處於良好狀態調整和不同(從TDD)技術和工具適用。

TDD爲您提供良好的設計,可靠的代碼和測試覆蓋安全網。這讓你成爲一個調整的好地方,但我認爲由於你和其他人引用的問題,它不會讓你在調整的道路上更進一步。我認爲,作爲TDD和實踐者的忠實粉絲和支持者,

+1

+1同意。 TDD確保當您調整系統時,不會中斷功能 – 2009-04-17 06:52:19

+0

如果提到任何*更好的技術,這個答案會更有幫助。 – bukzor 2013-10-30 20:47:59

+0

@bukzor OP似乎對概要分析和工具有很好的處理能力;問題是如何將TDD應用於此。我的回答是,這可能是不明智的;關於如何調整代碼的性能還有很多其他問題和答案。 – 2013-10-30 22:18:53

0

對於調整本身,您可以直接比較舊代碼和新代碼。但不要保留兩份副本。這聽起來像是一個噩夢來管理。另外,你只是將一個版本與另一個版本進行比較。功能的改變可能會降低你的功能,這是用戶可以接受的。

就我個人而言,我從來沒有見過類型的性能標準'必須比上一版本更快',因爲它很難衡量。

你說'嚴重需要性能調整'。哪裏?哪些查詢?哪些功能?誰說,企業,用戶?什麼是可接受的性能? 3秒? 2秒? 50毫秒?

任何性能分析的出發點都是定義合格/不合格標準。一旦你有了這個,你可以自動執行性能測試。

對於可靠性,您可以使用(簡單)統計方法。例如,在相同條件下運行相同的查詢100次。如果95%的人在n秒內返回,那就是合格。

就個人而言,我會在集成時從標準機器或集成服務器本身進行此操作。在某個地方記錄每個測試的值(巡航控制對這類事情有一些很好的功能)。如果你這樣做,你可以看到隨着時間的推移和每個構建的表現如何進步。你甚至可以製作一張圖。經理人喜歡圖表。

在進行性能測試時,無論您是否進行自動化測試,擁有穩定的環境總是很難做到。無論您如何開發(TDD,瀑布等),您都會遇到特殊問題。

+1

「我從來沒有見過類型的性能標準」必須比上一版本更快「」 WebKit人員對於性能迴歸具有零容忍策略。 – KaptajnKold 2009-04-17 09:05:50

+0

@KatajnKold很酷。這意味着我看到過一次:-) – 2009-04-17 10:18:46

0

還沒有面對這種情況;但是,如果我做了,這是我怎麼去做的。 (我想我是從Dave Astel的書中挑選出來的)

步驟#1:提出一個「可接受性能」的規範,例如,這可能意味着'用戶需要能夠在N秒內完成Y (或毫秒)'
步驟#2:現在編寫一個失敗的測試..使用友好的計時器類(例如.NET有StopWatch類)和Assert.Less(actualTime, MySpec)
步驟#3:如果測試已通過, 。如果是紅色,則需要優化並使其變爲綠色。一旦測試進入綠色,表現現在「可以接受」。

0

肯特貝克和他的團隊自動完成了TDD的所有測試。

這裏進行性能測試,我們也可以在TDD中自動執行測試。

這裏的標準,性能測試是要測試是或否的情況下

如果我們知道specfications很好ñ好,我們可以把它們也TDD

0

雖然我自動化與卡爾Manaster的回答大致同意,通過現代工具,可以獲得TDD爲功能測試提供的性能測試的一些優勢。使用最新的性能測試框架(我的大部分經驗是Gatling,但我相信大多數性能測試框架的新版本也是這樣),可以將自動化性能測試集成到持續集成構建中,並配置如果不符合性能要求,CI構建將失敗。如此提供,可以事先就您的性能要求達成一致(對於某些應用程序可能由與用戶或客戶同意的SLA驅動),如果更改導致性能問題,則可以提供快速反饋,並確定需要改進性能的領域。

良好的性能要求是「當每小時有5000個訂單時,95%的用戶旅程應該包含不超過10秒的等待時間,並且屏幕轉換時間不超過1秒」。

這也依賴於在CI管道中部署到生產類測試環境。

但是,使用性能需求來推動開發的方式可能與功能需求相同,這可能仍然不是一個好主意。通過功能需求,您通常可以瞭解應用程序在運行之前是否會通過測試,並且嘗試編寫您認爲可以通過的代碼是明智的。有了性能,trying to optimize code whose performance hasn't been measured is a dubious practice。您可以使用性能結果來驅動您的應用程序開發在一定程度上,只是沒有性能要求