こんにちは、この講義では Pharo での プロファイリングをお見せします。
プロファイリングでは 表現式の実行を計測することで
式を変更して
実行時間を節約できるかを見ます。
基本的に、プロファイリングすることで
実行速度を 40-50% 改善できると 言われています。
実際のところどうなのか ちゃんとした根拠は知りません。
Pharo でプロファイリングをするための
ツールをお見せします。
1つ目の方法は timeToRun という式です。
timeToRun はブロックに送るメッセージで
その式の実行時間を得ることができます。
ここに 1000 factorial がありますが
この 1000 factorial の実行時間を 計測するために、ブロックに入れて
timeToRun メッセージを送ります。
timeToRun を使って 2 つの式の 実行時間を簡単に比較することができます。
簡単な演習問題です。
select: してから collect: すると
select:thenCollect: より遅いかを
知りたいとします。 1 つ目の式は 2 つの段階を経ることになります。
2 つ目の式では 1 段階で済みます。
おそらく前者のほうが時間がかかるでしょう。 いずれにせよ、確認してみましょう。
まずは いずれの場合もコレクションを作ります。
10 要素からなる小さなコレクションです。
そして同じ回数だけ繰り返す
ループを作ります。
1 つ目の式では
コレクションから 5 より大きな要素だけを選んで
それから、選んだ要素の自乗を得ます。
2 つ目の式では 5 より大きな数を選んで
それを自乗しています。
計測すると、それぞれ 500 ミリ秒と
300 ミリ秒かかりました。 2 つ目の式のほうが良いことになります。
これで、やり方はわかったので あとはあなた次第です。
ただ、計測結果を大きくするために
両方の場合についてとても大きなループを いれなければならないこともあります。
別の方法として bench メッセージがあります。
bench メッセージで 5 秒の間に
そのコードが何回実行できるのかを計測します。
再び 1000 factorial を例にすると
1 秒で 610 回実行できます。
bench メッセージの場合には 改善するためには
数字が大きな方が良いことになります。
bench のバリエーションとして benchFor: で
計測時間を指定することができます。
ここに 2 seconds とありますが これは seconds メッセージで
2 に送られて 期間（時間幅）が得られます。
Duraction クラスのインスタンスです。
これでシステムが計測する時間を 操ることができます。
これもまた Pharo では全てがオブジェクトだ という実例です。
オブジェクト 2 に seconds メッセージを送って 計測時間を 2 秒にセットします。
次にプロファイラーをお見せします。
プロファイラーはサンプリングによるものです。
プログラムを実行して
一定間隔で
実行スタックを調べて
情報を集めます。
これを使うには TimeProfiler spyOn: を使って
ブロックを渡します。 20 回繰り返して
1000 factorial を計算して
結果をTranscript に表示します。
ここで通常は文字列への変換が 最もコストがかかります。
そしてプロファイラーが このように結果を
木構造でどの部分が最も時間がかかったかを 表示します。
今回は、実行時間の 63% が printOn:base: に費やされました。
こんな風にプロファイラーを
使うことができるということです。
まとめると
まずは
timeToRun: や bench や プロファイラーを使うことができます。
書籍「Deep into Pharo」では 1 つの章をつかって
この種の最適化技法を説明しています。
ここで大事なことは これら 3 つの例の
いずれもブロックを使うということです。 これもブロック
これもまたブロックです。なぜでしょう？
このコースの中で ブロックをつかって
表現式を凍結することを学びました。 ブロックを定義することは
そのまま実行することではありません。 bench メッセージが
実行回数を制御することができ
また、その式をいつ実行開始するかを 決めることができるのです。
もう 1 つ
timeToRun や bench がどう実装されているか 探してみてください。
表現式の上でクリックして
インプリメンター（implementors）で コードを見ることができます。