Golang を使用したベンチマーク

WBOY
リリース: 2024-09-05 21:31:03
オリジナル
904 人が閲覧しました

ゴーファーさん、こんにちは?

このブログ投稿では、#golang testing パッケージに組み込まれた素晴らしいツールの使用方法を説明します。コードまたは関数のパフォーマンスをどのようにテストしますか? ベンチマーク テストを使用します。

行きましょう

このテストでは、次のように決定される古典的なフィボナッチ数またはフィボナッチ数列を使用します。

if (x < 2) 
   F(0) = 1
   F(2) = 2
else 
   F(x) = F(x-1) + F(x-2)

In practice, the sequence is:
1, 1, 2, 3, 5, 8, 13, etc.
ログイン後にコピー

この順序は、以下に示すように、数学や自然のいくつかの部分にも現れるため、重要です。

Benchmark with Golang

このコードを実装するにはいくつかの方法がありますが、ベンチマーク テストには再帰的計算方法と反復計算方法の 2 つを選択します。関数の主な目的は、位置を提供し、その位置のフィボナッチ数を返すことです。

再帰的方法

// main.go

func fibRecursive(n int) int {
    if n <= 2 {
        return 1
    }
    return fibRecursive(n-1) + fibRecursive(n-2)
}
ログイン後にコピー

反復法

// main.go

func fibIterative(position uint) uint {
    slc := make([]uint, position)
    slc[0] = 1
    slc[1] = 1

    if position <= 2 {
        return 1
    }

    var result, i uint
    for i = 2; i < position; i++ {
        result = slc[i-1] + slc[i-2]
        slc[i] = result
    }

    return result
}
ログイン後にコピー

これらの方法は最適化されていませんが、テストの結果はたとえ少数であっても大きく異なります。これはテストでわかります。コードに従うには、ここをクリックしてください。

次に、ベンチマーク テストとして、_main_test.go ファイルにテストをいくつか書きましょう。 ベンチマーク に関する Golang のドキュメントを使用すると、次のようにテストする関数を作成できます:

// main_test.go

// The key is to start every function you want to benchmark with the keyword Benchmark and use b *testing.B instead of t *testing.T as input 
func BenchmarkFibIterative(b *testing.B) {
    // Use this for-loop to ensure the code will behave correctly. 
    // Now, you can put the function or piece of code you want to test
    for i := 0; i < b.N; i++ { 
        fibIterative(uint(100))
    }
}

// Same as above
func BenchmarkFibRecursive(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fibRecursive(100)
    }
}
ログイン後にコピー

先に進む前に質問します: どちらが速いですか?

小さい数値 (10) と少し大きい数値 (80) に対してテストを実行してみましょう。 ベンチマーク テストを実行するには、次のコマンドを実行するだけです:

go test -bench=関数名

このコマンドについて詳しく知りたい場合は、ここを確認してください。

最初のテスト:position=10

//(fibIterative)
Results:
cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibIterative-8         24491042                42.50 ns/op
PASS
ok      playground      1.651s
ログイン後にコピー

この画像を使って分析してみましょう:

Benchmark with Golang

画像によると、テストには 8 つのコアがあり、時間制限はありません (完了するまで実行されます)。タスクを完了するのに1.651秒かかりました。

==== Extra ====
We got 24,491,042 iterations (computations), and each iteration (op) took 42.50 ns.

Doing some math, we can calculate how much time one op took:

42.50 ns/op with 1 ns = 1/1,000,000,000 s
op ≈ 2.35270590588e-12 s
==== Extra ====
ログイン後にコピー

良い結果ですね。位置 10 の再帰関数を確認してみましょう:

// Results
BenchmarkFibRecursive-8          6035011               187.8 ns/op
PASS
ok      playground      1.882s
ログイン後にコピー

タスクを完了するのに 1.882 秒かかったことがわかります。

反復関数が数デシ秒の差で勝利しました。次のテストをもう 1 つ試してみましょう:

位置 50

// Results for the Iterative Function

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibIterative-8         27896118                45.37 ns/op
PASS
ok      playground      2.876s

// Results for the Recursive Function

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibRecursive-8          6365198               186.3 ns/op
PASS
ok      playground      1.918s
ログイン後にコピー

うわー!再帰関数の方が高速になったのでしょうか?

少し大きな数字で終わりましょう。

位置 80

// Results for the Iterative Function

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibIterative-8          5102344               229.5 ns/op
PASS
ok      playground      1.933s

// Results for the Recursive Function
// My poor PC couldn’t handle it, so I had to reduce the position to 50 just to get some results printed.

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibRecursive-8                1        44319299474 ns/op
PASS
ok      playground      44.951s
ログイン後にコピー

その違いは大きいです。位置 80 の場合、反復アプローチには約 2 秒かかりました。位置 50 の場合、再帰関数には約 45 秒かかりました。これは、Golang プロジェクトの速度が低下し始めたときにコードのベンチマークを行うことの重要性を示しています。

結論

実稼働コードの実行が遅い、または予測できないほど遅い場合は、この手法を pprof または組み込みテスト パッケージの他のツールと組み合わせて使用​​し、コードがどこで実行されているかを特定してテストできます。不十分な点とそれを最適化する方法。

補足: 見た目に美しいコードのすべてがパフォーマンスが高いわけではありません。

追加の演習

再帰関数を改善するより良い方法を見つけることはできますか? (ヒント: 動的プログラミングを使用してください)。この記事では、一部の数値が小さい場合、再帰戦略が優れている理由を説明します。

以上がGolang を使用したベンチマークの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!