Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 13980] ファイルの概要

このコミットは、Go言語の標準ライブラリであるtestingパッケージ内のベンチマーク結果出力に関する変更です。具体的には、ベンチマーク結果のメモリ使用量に関する文字列出力において、冗長な空白(タブ文字)を削除し、出力の整形を改善することを目的としています。

コミット

  • コミットハッシュ: 4bf6249ba5f168b8b5f0115fe638bdf2740a8011
  • Author: Eric Roshan-Eisner eric.d.eisner@gmail.com
  • Date: Fri Sep 28 10:01:09 2012 +1000

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/4bf6249ba5f168b8b5f0115fe638bdf2740a8011

元コミット内容

testing: remove redundant whitespace in output

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/6565061

変更の背景

Go言語のtestingパッケージは、ユニットテスト、ベンチマークテスト、および例(Example)の実行をサポートする標準ライブラリです。ベンチマークテストは、コードのパフォーマンスを測定するために使用され、go test -benchコマンドで実行されます。このコマンドの出力には、実行時間だけでなく、メモリ割り当てに関する情報(1操作あたりのバイト数、1操作あたりの割り当て回数)も含まれます。

このコミットが行われる前は、ベンチマーク結果のメモリ関連の出力に余分なタブ文字(\t)が含まれていました。これにより、出力の整形が意図せず崩れたり、他の出力とのアラインメントが合わなくなったりする可能性がありました。この変更は、出力の視覚的な整合性と可読性を向上させるために、この冗長な空白を削除することを目的としています。

前提知識の解説

Go言語の testing パッケージ

testingパッケージは、Goプログラムの自動テストをサポートするためのGoの標準ライブラリです。

  • テスト関数: func TestXxx(*testing.T) の形式で記述され、ユニットテストを実行します。
  • ベンチマーク関数: func BenchmarkXxx(*testing.B) の形式で記述され、コードのパフォーマンスを測定します。*testing.B 型は、ベンチマークの実行回数を制御したり、メモリ割り当てを記録したりするためのメソッドを提供します。
  • go test コマンド: Goのテストを実行するためのコマンドです。
    • go test: 通常のテストを実行します。
    • go test -bench=.: ベンチマークテストを実行します。

testing.BenchmarkResult 構造体

testingパッケージには、ベンチマークテストの結果を保持するためのBenchmarkResult構造体があります。この構造体は、ベンチマークの実行時間、操作回数、メモリ割り当てに関する情報などをカプセル化します。

String() および MemString() メソッド

Go言語では、型にString() stringメソッドを定義することで、その型の値を文字列として表現する方法をカスタマイズできます。testing.BenchmarkResult構造体には、ベンチマーク結果全体を文字列として整形するString()メソッドと、メモリ割り当てに関する部分を文字列として整形するMemString()メソッドが定義されています。

  • String(): ベンチマークの実行時間や操作回数など、主要な結果を整形して返します。
  • MemString(): 1操作あたりのメモリ割り当てバイト数(B/op)と、1操作あたりのメモリ割り当て回数(allocs/op)を整形して返します。

fmt.Sprintf 関数

fmtパッケージのSprintf関数は、指定されたフォーマット文字列と引数を使用して、フォーマットされた文字列を生成します。C言語のsprintfに似ています。

  • \t: タブ文字を表すエスケープシーケンスです。
  • %8d: 整数を少なくとも8文字幅で右寄せして表示するためのフォーマット指定子です。

技術的詳細

このコミットの技術的な変更は非常にシンプルですが、出力の整形に直接影響を与えます。変更はsrc/pkg/testing/benchmark.goファイル内のMemString()メソッドにあります。

変更前:

func (r BenchmarkResult) MemString() string {
	return fmt.Sprintf("\t%8d B/op\t%8d allocs/op",
		r.AllocedBytesPerOp(), r.AllocsPerOp())
}

変更後:

func (r BenchmarkResult) MemString() string {
	return fmt.Sprintf("%8d B/op\t%8d allocs/op",
		r.AllocedBytesPerOp(), r.AllocsPerOp())
}

変更点は、fmt.Sprintfのフォーマット文字列の先頭から\t(タブ文字)が削除されたことです。

変更の影響

  • 変更前: MemString()が返す文字列は、常に先頭にタブ文字が含まれていました。これは、BenchmarkResultString()メソッド内でMemString()が呼び出される際に、すでに適切なインデントが適用されている場合、二重のインデント(余分な空白)を引き起こす可能性がありました。
  • 変更後: MemString()が返す文字列は、先頭にタブ文字を含まなくなりました。これにより、BenchmarkResultString()メソッドや、MemString()を直接呼び出す他の場所で、より柔軟かつ正確な出力整形が可能になります。出力の冗長な空白が解消され、ベンチマーク結果の表示がよりクリーンになります。

この変更は、機能的な動作には影響を与えず、純粋に出力の整形と可読性の向上を目的としています。

コアとなるコードの変更箇所

--- a/src/pkg/testing/benchmark.go
+++ b/src/pkg/testing/benchmark.go
@@ -256,7 +256,7 @@ func (r BenchmarkResult) String() string {
 }
 
 func (r BenchmarkResult) MemString() string {
-	return fmt.Sprintf("\t%8d B/op\t%8d allocs/op",
+	return fmt.Sprintf("%8d B/op\t%8d allocs/op",
 		r.AllocedBytesPerOp(), r.AllocsPerOp())
 }

コアとなるコードの解説

上記の差分は、src/pkg/testing/benchmark.goファイル内のBenchmarkResult型のMemString()メソッドに対する変更を示しています。

MemString()メソッドは、ベンチマーク結果のメモリ割り当てに関する情報を文字列としてフォーマットするために使用されます。具体的には、r.AllocedBytesPerOp()(1操作あたりの割り当てバイト数)とr.AllocsPerOp()(1操作あたりの割り当て回数)の2つの値を整形します。

変更前は、fmt.Sprintfのフォーマット文字列が"\t%8d B/op\t%8d allocs/op"となっていました。この先頭の\tが、生成される文字列の冒頭にタブ文字を追加していました。

変更後は、フォーマット文字列が"%8d B/op\t%8d allocs/op"となり、先頭の\tが削除されています。これにより、MemString()が返す文字列は、メモリ割り当て情報が直接%8d B/opから始まるようになり、余分なインデントがなくなります。

この修正により、go test -benchの出力において、メモリ関連の統計情報がより適切に整列され、全体的な出力の視認性が向上します。

関連リンク

参考にした情報源リンク

  • Go言語公式ドキュメント: testingパッケージ (https://pkg.go.dev/testing)
  • Go言語公式ドキュメント: fmtパッケージ (https://pkg.go.dev/fmt)
  • Go言語のベンチマークに関する公式ブログ記事やチュートリアル (一般的な知識として参照)