您好,登錄后才能下訂單哦!
小編給大家分享一下c++性能測試工具之計算時間復雜度的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
google benchmark已經為我們提供了類似的功能,而且使用相當簡單。
具體的解釋在后面,我們先來看幾個例子,我們人為制造幾個時間復雜度分別為O(n), O(logn), O(n^n)的測試用例:
// 這里都是為了演示而寫成的代碼,沒有什么實際意義 static void bench_N(benchmark::State& state) { int n = 0; for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(n += 2); // 這個函數防止編譯器將表達式優化,會略微降低一些性能 } } state.SetComplexityN(state.range(0)); } BENCHMARK(bench_N)->RangeMultiplier(10)->Range(10, 1000000)->Complexity(); static void bench_LogN(benchmark::State& state) { int n = 0; for ([[maybe_unused]] auto _ : state) { for (int i = 1; i < state.range(0); i *= 2) { benchmark::DoNotOptimize(n += 2); } } state.SetComplexityN(state.range(0)); } BENCHMARK(bench_LogN)->RangeMultiplier(10)->Range(10, 1000000)->Complexity(); static void bench_Square(benchmark::State& state) { int n = 0; auto len = state.range(0); for ([[maybe_unused]] auto _ : state) { for (int64_t i = 1; i < len*len; ++i) { benchmark::DoNotOptimize(n += 2); } } state.SetComplexityN(len); } BENCHMARK(bench_Square)->RangeMultiplier(10)->Range(10, 100000)->Complexity();
如何傳遞參數和生成批量測試我們在上一篇已經介紹過了,這里不再重復。
需要關注的是新出現的state.SetComplexityN和Complexity。
首先是state.SetComplexityN,參數是一個64位整數,用來表示算法總體需要處理的數據總量。benchmark會根據這個數值,再加上運行耗時以及state的迭代次數計算出一個用于后面預估*均時間復雜度的值。
Complexity會根據同一組的多個測試用例計算出一個較接*的*均時間復雜度和一個均方根值,需要和state.SetComplexityN配合使用。
Complexity還有一個參數,可以接受一個函數或是benchmark::BigO枚舉,它的作用是提示benchmark該測試用例的時間復雜度,默認值為benchmark::oAuto,測試中會自動幫我們計算出時間復雜度。對于較為復雜的算法,而我們又有預期的時間按復雜度,這時我們就可以將其傳給這個方法,比如對于第二個測試用例,我們還可以這樣寫:
static void bench_LogN(benchmark::State& state) { // 中間部分與前面一樣,略過 } BENCHMARK(bench_LogN)->RangeMultiplier(10)->Range(10, 1000000)->Complexity(benchmark::oLogN);
在選擇正確的提示后對測試結果幾乎沒有影響,除了偏差值可以降得更低,使結果更準確。
Complexity在計算時間復雜度時會保留復雜度的系數,因此,如果我們發現給出的提示的時間復雜度前的系數過大的話,就意味著我們的預估發生了較大的偏差,同時它還會計算出RMS值,同樣反應了時間復雜度的偏差情況。
運行我們的測試:
可以看到,自動的時間復雜度計算基本是準確的,可以在我們對算法進行測試時提供一個有效的參考。
看完了這篇文章,相信你對“c++性能測試工具之計算時間復雜度的示例分析”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。