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

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

このコミットは、Go言語のベンチマークスイートである test/bench/shootout ディレクトリ内の timing.sh スクリプトに対する変更です。timing.sh は、様々なベンチマークプログラム(特にThe Computer Language Benchmarks Gameのベンチマーク)の実行時間を計測し、Go言語の実装と他の言語(C言語など)の実装を比較するために使用されます。この変更の主な目的は、テストモードにおいてC言語ライブラリへの依存を取り除くことです。

コミット

このコミットは、test/bench/shootout/timing.sh スクリプトにおいて、ベンチマーク実行時にC言語で書かれたプログラムが特定のCライブラリ(pcreglib-2.0gmp)に依存している部分を、テストモード(runonly コマンドを使用するケース)では実行しないように修正しています。これにより、テスト環境でのビルドや実行時の外部Cライブラリ依存による問題を回避し、Go言語のベンチマークテストの安定性と移植性を向上させています。

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

https://github.com/golang/go/commit/13802f565400a91519df86902ece3bd0a8c5aadb

元コミット内容

commit 13802f565400a91519df86902ece3bd0a8c5aadb
Author: Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
Date:   Sun Jun 24 19:23:09 2012 -0400

    test/bench/shootout: remove dependency on C libraries in test mode
    Fixes #3732.
    
    R=golang-dev
    CC=golang-dev
    https://golang.org/cl/6335053

変更の背景

この変更は、Go issue #3732「test/bench/shootout が外部Cライブラリに依存しているため、テストの実行が困難」を修正するために行われました。

Go言語のベンチマークスイートである test/bench/shootout には、C言語で書かれたベンチマークプログラムも含まれており、これらの中には pcre (Perl Compatible Regular Expressions)、glib-2.0 (GLibライブラリ)、gmp (GNU Multiple Precision Arithmetic Library) といった外部のCライブラリに依存するものがありました。

これらの外部Cライブラリは、Goのテスト環境が常に利用できるとは限りません。特に、CI/CD環境や特定の開発者のローカル環境では、これらのライブラリがインストールされていない、または適切なバージョンが利用できない場合があります。その結果、ベンチマークテストを実行しようとすると、ライブラリが見つからない、リンクエラーが発生するなどの問題が生じ、テストが失敗していました。

このコミットの目的は、ベンチマークの「テストモード」(runonly コマンドで実行される部分)において、これらのCライブラリへの依存を排除することです。これにより、Goのベンチマークテストがより安定して実行できるようになり、外部依存によるテストの失敗を防ぎ、開発者がGoのベンチマークをより容易に実行・検証できるようになります。

前提知識の解説

  • The Computer Language Benchmarks Game (Shootout): 異なるプログラミング言語の実装を比較するためのベンチマークスイート。Go言語のベンチマークスイート test/bench/shootout は、このベンチマークゲームから派生したものです。
  • test/bench/shootout/timing.sh: Go言語のソースコードリポジトリ内のシェルスクリプトで、Shootoutベンチマークを実行し、その実行時間を計測するために使用されます。
  • gcc: GNU Compiler Collection。C、C++、Goなどの様々なプログラミング言語をコンパイルできるコンパイラ群。
  • gccgo: GCCのGo言語フロントエンド。GoプログラムをGCCのバックエンドを使ってコンパイルします。
  • gc: Go言語の公式コンパイラ(go tool compile)。
  • runrunonly: timing.sh スクリプト内で定義されている関数。
    • run: ベンチマークを実行し、その結果を記録するための関数。通常、実際のベンチマーク計測に使用されます。
    • runonly: ベンチマークの準備段階や、特定の条件でのみ実行されるべきコマンドに使用される関数。この関数で実行されるコマンドは、実際のベンチマーク結果には影響を与えない、またはテスト環境でのみ必要な処理であることが多いです。このコミットでは、runonly を使用することで、Cライブラリに依存するベンチマークを「テストモード」でのみ実行しないように制御しています。
  • pkg-config: コンパイル時に必要なライブラリのパスやコンパイラフラグ、リンカフラグなどを取得するためのツール。glib-2.0 のようなライブラリのコンパイル・リンクに必要な情報を取得する際に使用されます。
  • pcre (Perl Compatible Regular Expressions): Perl互換の正規表現ライブラリ。
  • glib-2.0 (GLib): GTK+などのGNOMEプロジェクトで広く使われているユーティリティライブラリ。データ構造、スレッド、イベントループなど、様々な機能を提供します。
  • gmp (GNU Multiple Precision Arithmetic Library): 任意精度演算(非常に大きな整数や浮動小数点数を扱う)のためのライブラリ。pidigits のような数値計算ベンチマークで使われることがあります。
  • シェルスクリプトの条件分岐 (if [ $mode = run ]; then ... fi): シェルスクリプトにおける条件分岐の構文。ここでは、スクリプトの実行モードが run である場合にのみ、特定のコマンドを実行するように制御しています。

技術的詳細

このコミットの技術的な核心は、timing.sh スクリプト内で使用されている run 関数と runonly 関数の使い分けにあります。

元のスクリプトでは、regexdnak-nucleotidepidigits といったベンチマークにおいて、C言語版の実装が外部Cライブラリ(pcre, glib-2.0, gmp)に依存していました。これらのC言語版ベンチマークは、run 関数を使って実行されていました。

run 関数は、実際のベンチマーク計測のために使用されるため、その実行にはすべての依存関係が満たされている必要があります。しかし、テスト環境ではこれらの外部Cライブラリが常に利用可能であるとは限りません。

このコミットでは、これらのC言語版ベンチマークの実行を runonly 関数に切り替えるか、または特定のモードでのみ実行するように条件分岐を追加しています。

  • regexdnapidigits:
    • これらのベンチマークでは、C言語版の実行が run から runonly に変更されました。
    • runonly は、ベンチマークの準備段階や、実際の計測には含まれないが、テストやデバッグのために実行されるべきコマンドに使用されます。これにより、これらのC言語版ベンチマークが、外部Cライブラリが利用できないテスト環境で実行されることを防ぎます。
  • k-nucleotide:
    • このベンチマークでは、C言語版の実行が if [ $mode = run ]; then ... fi という条件分岐の中に移動されました。
    • これは、スクリプトが「run モード」で実行されている場合にのみ、C言語版のベンチマークが実行されることを意味します。run モードは、通常、完全なベンチマーク計測を行う際に使用されるモードであり、このモードでは外部Cライブラリの存在が期待されます。しかし、それ以外のテストモードでは、このC言語版ベンチマークはスキップされます。

この変更により、Goのベンチマークスイートは、外部Cライブラリの有無に左右されずに、より広範な環境で安定してテストを実行できるようになりました。これは、Goのテストインフラストラクチャの堅牢性を高める上で重要な改善です。

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

diff --git a/test/bench/shootout/timing.sh b/test/bench/shootout/timing.sh
index 8758549bde..47707e7438 100755
--- a/test/bench/shootout/timing.sh
+++ b/test/bench/shootout/timing.sh
@@ -126,7 +126,7 @@ regexdna() {\
 	runonly gcc -O2 fasta.c
 	runonly a.out 100000 > x
 	runonly echo 'regex-dna 100000'
-	run 'gcc -O2 regex-dna.c -lpcre' a.out <x
+	runonly 'gcc -O2 regex-dna.c -lpcre' a.out <x
 	run 'gccgo -O2 regex-dna.go' a.out <x
 	run 'gccgo -O2 regex-dna-parallel.go' a.out <x
 	run 'gc regex-dna' $O.out <x
@@ -147,7 +147,9 @@ knucleotide() {\
 	runonly gcc -O2 fasta.c
 	runonly a.out 1000000 > x  # should be using 25000000
 	runonly echo 'k-nucleotide 1000000'
-	run "gcc -O2 k-nucleotide.c $(pkg-config glib-2.0 --cflags --libs)" a.out <x
+	if [ $mode = run ]; then
+		run "gcc -O2 k-nucleotide.c $(pkg-config glib-2.0 --cflags --libs)" a.out <x
+	fi
 	run 'gccgo -O2 k-nucleotide.go' a.out <x
 	run 'gccgo -O2 k-nucleotide-parallel.go' a.out <x
 	run 'gc k-nucleotide' $O.out <x
@@ -174,7 +176,7 @@ meteor() {\
 
 pidigits() {\
 	runonly echo 'pidigits 10000'
-	run 'gcc -O2 pidigits.c -lgmp' a.out 10000
+	runonly 'gcc -O2 pidigits.c -lgmp' a.out 10000
 	run 'gccgo -O2 pidigits.go' a.out -n 10000
 	run 'gc pidigits' $O.out -n 10000
 	run 'gc_B  pidigits' $O.out -n 10000

コアとなるコードの解説

上記のdiffは、timing.sh スクリプト内の3つのベンチマーク関数 regexdnaknucleotidepidigits における変更を示しています。

  1. regexdna 関数 (-lpcre 依存):

    -	run 'gcc -O2 regex-dna.c -lpcre' a.out <x
    +	runonly 'gcc -O2 regex-dna.c -lpcre' a.out <x
    
    • 変更前: regex-dna.cpcre ライブラリにリンクして run 関数で実行していました。
    • 変更後: runrunonly に変更しました。これにより、regex-dna.c のコンパイルと実行は、実際のベンチマーク計測の対象から外され、テストモードではスキップされるようになります。pcre ライブラリがシステムにインストールされていない場合でも、テストが失敗しなくなります。
  2. knucleotide 関数 (glib-2.0 依存):

    -	run "gcc -O2 k-nucleotide.c $(pkg-config glib-2.0 --cflags --libs)" a.out <x
    +	if [ $mode = run ]; then
    +		run "gcc -O2 k-nucleotide.c $(pkg-config glib-2.0 --cflags --libs)" a.out <x
    +	fi
    
    • 変更前: k-nucleotide.cglib-2.0 ライブラリにリンクして run 関数で実行していました。
    • 変更後: run コマンド全体が if [ $mode = run ]; then ... fi という条件分岐で囲まれました。これは、スクリプトが run モード(完全なベンチマーク計測モード)で実行されている場合にのみ、このC言語版のベンチマークが実行されることを意味します。それ以外のモード(例えば、テストやCI環境でのクイックチェック)では、このC言語版ベンチマークはスキップされ、glib-2.0 の依存関係による問題が回避されます。
  3. pidigits 関数 (-lgmp 依存):

    -	run 'gcc -O2 pidigits.c -lgmp' a.out 10000
    +	runonly 'gcc -O2 pidigits.c -lgmp' a.out 10000
    
    • 変更前: pidigits.cgmp ライブラリにリンクして run 関数で実行していました。
    • 変更後: runrunonly に変更しました。regexdna と同様に、pidigits.c のコンパイルと実行は、実際のベンチマーク計測の対象から外され、テストモードではスキップされるようになります。gmp ライブラリがシステムにインストールされていない場合でも、テストが失敗しなくなります。

これらの変更により、Goのベンチマークスイートは、外部Cライブラリの依存関係によるテストの不安定性を大幅に軽減し、より堅牢で移植性の高いテスト環境を提供できるようになりました。

関連リンク

参考にした情報源リンク