« 言語の冗長さはコンパイラのためにある | トップページ | ソフトウエア工学は工学的になれるか »

2008年5月10日 (土)

ベンチマークなんて必要ですか?

適当な意見だなー、そのシンタックスシュガーとやらをなくすとコンパイル時間が何ミリ秒速くなるんだよ。絶対ベンチ取らずに思いつきで言ってる

http://twitter.com/todesking/statuses/806986776

まあ、適当なことを言っている、というのは否定しませんけど。

言語仕様がシンプルな方が、コンパイル時間を短くできる、というのは一般論としてあるわけでして、別に私のオリジナルな思いつき、というものではないですよ。

翻訳過程での込み入った複雑さを少なくできる唯一の方法は、明確に定義され構造が整っているソース言語を選択することである。

二クラウス・ヴィルト 著, 滝沢徹・牧野祐子訳, 『コンパイラ構成法』, アジソン・ウェスレイ, 1997, p.1

原始プログラムを効率のよい目的プログラムに翻訳したいだろうし、翻訳の過程そのものも効率化したいだろう。どちらの場合にも、言語の設計が、それらの計算がどの程度簡単に行なえるかということに影響を及ぼし得る。

A.V.エイホ ・ J.D.ウルマン著, 土居範久 訳, 『コンパイラ』, 倍風館, 1986, P.25

確か、C言語の設計思想について、もっと明確に、コンパイラに楽をさせるためである、としていた本があったと思うのですが。ベル研究所の関係者が書いたもので。すみませんが、何だったか、思い出せないし、今本棚探しても見つかりません。

ベンチマークなのですが。言語設計の違いが、コンパイル時間に有意な差をもたらすかどうか、などというような研究は、私の手には負えません。といいますか、個人の力では無理でしょう。ですので、以下に示すものも”超適当”なもので、何の証拠にもなりませんよ、と前おきさせていただきまして。

Java言語の拡張for文と、従来のfor文で、コンパイル時間に差がつくか、を試してみました。もともと、Java言語には、シンタックス・シュガーなるものはほとんど存在しないわけですが(それが設計思想だと思います)、『Java言語仕様 第3版』によりますと:

拡張for文の意味は、基本for文へと変換することによって与えられる。

p.343

とありますので、拡張for文はシンタックス・シュガーである、と考えて良さそうです。

でまあ、以下のような Rubyスクリプトで、10,000個のソースファイルを2セット作りました。 Test1 は拡張for文、 Test2 は基本for文です。

#genTest1.rb
(1..10000).each do |i|
File.open("01/src/Test#{i}.java", "w") do |out|
out.print <<EOS
public class Test#{i} {

  public void test() {
    int[] a = new int[101];
    for (int i = 0; i < a.length; i++)
      a[i] = i;
    int sum = 0;
    for (int i : a)
      sum += i;
    System.out.println(sum);
  }

}
EOS
end
end

#genTest2.rb
(1..10000).each do |i|
File.open("02/src/Test#{i}.java", "w") do |out|
out.print <<EOS
public class Test#{i} {

  public void test() {
    int[] a = new int[101];
    for (int i = 0; i < a.length; i++)
      a[i] = i;
    int sum = 0;
    for (int i = 0; i < a.length; i++)
      sum += i;
    System.out.println(sum);
  }

}
EOS
end
end

こうやって作ったソースファイルを、Antを使ってコンパイルしてみます。 使った build.xml は以下のとおり。

<project name="MyProject1" default="compile" basedir=".">

<target name="clean">
<delete>
  <fileset dir="bin" includes="*.class" />
</delete>
</target>

<target name="compile">
  <javac srcdir="src" destdir="bin" />
</target>

</project>

javac と ant のバージョンは以下のとおり。

>javac -version
javac 1.5.0_14
>ant -version
Apache Ant version 1.7.0 compiled on December 13 2006

Test1(拡張for文) の結果です。

01>ant
Buildfile: build.xml

compile:
    [javac] Compiling 10000 source files to 01\bin

BUILD SUCCESSFUL
Total time: 1 minute 40 seconds

Test2(基本for文) の結果です。

02>ant
Buildfile: build.xml

compile:
    [javac] Compiling 10000 source files to 02\bin

BUILD SUCCESSFUL
Total time: 1 minute 30 seconds

ということで、拡張for文の方がコンパイル時間が10秒ほど遅くなりました。上の結果を出すのに、一応、”ウォーム・アップ”はしました(つまりそれぞれ2回ずつ実行した)。まあ、統計とって分析したわけではありませんので、この結果にたいした意味はないでしょうけど。

|

« 言語の冗長さはコンパイラのためにある | トップページ | ソフトウエア工学は工学的になれるか »

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/80472/20866163

この記事へのトラックバック一覧です: ベンチマークなんて必要ですか?:

« 言語の冗長さはコンパイラのためにある | トップページ | ソフトウエア工学は工学的になれるか »