WEBVTT

00:00:00.720 --> 00:00:05.440 align:middle
こんにちは、この講義では Pharo での
プロファイリングをお見せします。

00:00:05.600 --> 00:00:08.640 align:middle
プロファイリングでは
表現式の実行を計測することで

00:00:08.800 --> 00:00:11.320 align:middle
式を変更して

00:00:11.480 --> 00:00:13.520 align:middle
実行時間を節約できるかを見ます。

00:00:14.560 --> 00:00:18.360 align:middle
基本的に、プロファイリングすることで

00:00:18.520 --> 00:00:22.920 align:middle
実行速度を 40-50% 改善できると
言われています。

00:00:23.080 --> 00:00:26.240 align:middle
実際のところどうなのか
ちゃんとした根拠は知りません。

00:00:26.400 --> 00:00:29.160 align:middle
Pharo でプロファイリングをするための

00:00:29.320 --> 00:00:32.160 align:middle
ツールをお見せします。

00:00:32.320 --> 00:00:35.800 align:middle
1つ目の方法は timeToRun という式です。

00:00:35.960 --> 00:00:38.320 align:middle
timeToRun はブロックに送るメッセージで

00:00:38.480 --> 00:00:40.720 align:middle
その式の実行時間を得ることができます。

00:00:40.880 --> 00:00:43.680 align:middle
ここに 1000 factorial がありますが

00:00:43.840 --> 00:00:48.120 align:middle
この 1000 factorial の実行時間を
計測するために、ブロックに入れて

00:00:48.280 --> 00:00:50.600 align:middle
timeToRun メッセージを送ります。

00:00:50.760 --> 00:00:55.120 align:middle
timeToRun を使って 2 つの式の
実行時間を簡単に比較することができます。

00:00:55.280 --> 00:00:57.520 align:middle
簡単な演習問題です。

00:00:57.680 --> 00:01:00.720 align:middle
select: してから collect: すると

00:01:00.880 --> 00:01:05.280 align:middle
select:thenCollect: より遅いかを

00:01:05.440 --> 00:01:08.400 align:middle
知りたいとします。
1 つ目の式は 2 つの段階を経ることになります。

00:01:08.560 --> 00:01:10.600 align:middle
2 つ目の式では 1 段階で済みます。

00:01:10.760 --> 00:01:14.120 align:middle
おそらく前者のほうが時間がかかるでしょう。
いずれにせよ、確認してみましょう。

00:01:14.840 --> 00:01:17.560 align:middle
まずは
いずれの場合もコレクションを作ります。

00:01:17.720 --> 00:01:21.920 align:middle
10 要素からなる小さなコレクションです。

00:01:22.080 --> 00:01:26.200 align:middle
そして同じ回数だけ繰り返す

00:01:27.360 --> 00:01:31.000 align:middle
ループを作ります。

00:01:31.160 --> 00:01:32.960 align:middle
1 つ目の式では

00:01:33.120 --> 00:01:38.000 align:middle
コレクションから
5 より大きな要素だけを選んで

00:01:38.160 --> 00:01:41.920 align:middle
それから、選んだ要素の自乗を得ます。

00:01:42.080 --> 00:01:45.960 align:middle
2 つ目の式では
5 より大きな数を選んで

00:01:46.120 --> 00:01:49.840 align:middle
それを自乗しています。

00:01:50.000 --> 00:01:53.360 align:middle
計測すると、それぞれ
500 ミリ秒と

00:01:53.520 --> 00:01:57.320 align:middle
300 ミリ秒かかりました。
2 つ目の式のほうが良いことになります。

00:01:57.480 --> 00:01:59.960 align:middle
これで、やり方はわかったので
あとはあなた次第です。

00:02:00.120 --> 00:02:05.800 align:middle
ただ、計測結果を大きくするために

00:02:06.560 --> 00:02:11.600 align:middle
両方の場合についてとても大きなループを
いれなければならないこともあります。

00:02:12.080 --> 00:02:16.800 align:middle
別の方法として
bench メッセージがあります。

00:02:16.960 --> 00:02:20.520 align:middle
bench メッセージで
5 秒の間に

00:02:20.680 --> 00:02:26.240 align:middle
そのコードが何回実行できるのかを計測します。

00:02:27.560 --> 00:02:31.560 align:middle
再び 1000 factorial を例にすると

00:02:31.720 --> 00:02:33.840 align:middle
1 秒で 610 回実行できます。

00:02:34.000 --> 00:02:37.000 align:middle
bench メッセージの場合には
改善するためには

00:02:37.160 --> 00:02:39.320 align:middle
数字が大きな方が良いことになります。

00:02:39.480 --> 00:02:42.680 align:middle
bench のバリエーションとして
benchFor: で

00:02:42.840 --> 00:02:46.800 align:middle
計測時間を指定することができます。

00:02:46.960 --> 00:02:50.000 align:middle
ここに 2 seconds とありますが
これは seconds メッセージで

00:02:50.160 --> 00:02:54.920 align:middle
2 に送られて
期間（時間幅）が得られます。

00:02:55.080 --> 00:02:57.480 align:middle
Duraction クラスのインスタンスです。

00:02:58.120 --> 00:03:01.080 align:middle
これでシステムが計測する時間を
操ることができます。

00:03:01.240 --> 00:03:04.960 align:middle
これもまた Pharo では全てがオブジェクトだ
という実例です。

00:03:05.120 --> 00:03:09.240 align:middle
オブジェクト 2 に seconds メッセージを送って
計測時間を 2 秒にセットします。

00:03:10.600 --> 00:03:15.080 align:middle
次にプロファイラーをお見せします。

00:03:15.240 --> 00:03:16.880 align:middle
プロファイラーはサンプリングによるものです。

00:03:17.040 --> 00:03:20.520 align:middle
プログラムを実行して

00:03:20.680 --> 00:03:23.880 align:middle
一定間隔で

00:03:24.040 --> 00:03:26.400 align:middle
実行スタックを調べて

00:03:26.560 --> 00:03:29.040 align:middle
情報を集めます。

00:03:29.200 --> 00:03:33.760 align:middle
これを使うには
TimeProfiler spyOn: を使って

00:03:33.920 --> 00:03:37.800 align:middle
ブロックを渡します。
20 回繰り返して

00:03:37.960 --> 00:03:39.680 align:middle
1000 factorial を計算して

00:03:39.840 --> 00:03:42.000 align:middle
結果をTranscript に表示します。

00:03:42.160 --> 00:03:45.920 align:middle
ここで通常は文字列への変換が
最もコストがかかります。

00:03:46.080 --> 00:03:50.480 align:middle
そしてプロファイラーが
このように結果を

00:03:50.640 --> 00:03:55.080 align:middle
木構造でどの部分が最も時間がかかったかを
表示します。

00:03:55.240 --> 00:04:00.000 align:middle
今回は、実行時間の 63% が
printOn:base: に費やされました。

00:04:01.040 --> 00:04:03.240 align:middle
こんな風にプロファイラーを

00:04:03.400 --> 00:04:06.960 align:middle
使うことができるということです。

00:04:07.960 --> 00:04:09.240 align:middle
まとめると

00:04:09.480 --> 00:04:10.640 align:middle
まずは

00:04:10.800 --> 00:04:14.600 align:middle
timeToRun: や bench や
プロファイラーを使うことができます。

00:04:14.760 --> 00:04:19.280 align:middle
書籍「Deep into Pharo」では
1 つの章をつかって

00:04:19.440 --> 00:04:22.560 align:middle
この種の最適化技法を説明しています。

00:04:22.720 --> 00:04:26.240 align:middle
ここで大事なことは
これら 3 つの例の

00:04:26.400 --> 00:04:30.440 align:middle
いずれもブロックを使うということです。
これもブロック

00:04:30.600 --> 00:04:33.400 align:middle
これもまたブロックです。なぜでしょう？

00:04:33.560 --> 00:04:36.680 align:middle
このコースの中で
ブロックをつかって

00:04:36.840 --> 00:04:39.520 align:middle
表現式を凍結することを学びました。
ブロックを定義することは

00:04:39.680 --> 00:04:42.560 align:middle
そのまま実行することではありません。
bench メッセージが

00:04:42.720 --> 00:04:44.920 align:middle
実行回数を制御することができ

00:04:45.080 --> 00:04:48.080 align:middle
また、その式をいつ実行開始するかを
決めることができるのです。

00:04:48.240 --> 00:04:50.080 align:middle
もう 1 つ

00:04:50.240 --> 00:04:54.680 align:middle
timeToRun や bench がどう実装されているか
探してみてください。

00:04:54.840 --> 00:04:57.520 align:middle
表現式の上でクリックして

00:04:57.680 --> 00:05:00.840 align:middle
インプリメンター（implementors）で
コードを見ることができます。

