や、言語関係など覚えたいもの、覚えるべきものはたくさんある一方で、注目が集まっているから、やってみたい。ということでプログラミング言語としてのを学んでいく。
4. Juliaの高速化
4.1 プロファイリング
プログラムを高速化するには、コード処理にかかる時間を計測するプロファイリングが肝要である。プログラムの中で実行に特に時間のかかっている部分をボトルネックという。プロファイリングを行なうことでボトルネックを効率的に発見することが、高速化に向けた第一歩である。
4.1.1 高速化の事前準備
まずプロファイルを行なう前提として、対象のプログラムが望んだ通りに正しく動作することを確認する。
次に、その正しい状態を維持するためのテストを用意する。プロファイリング後のチューニングではコードを書き換えるため、誤ってプログラムの動作を変えることを防ぐべくテストは必須である。
動作確認のテストは可能な限り簡単にできるようにしておく。
例:配列の操作計算
配列の総和を計算する関数を定義するとしたら、などの名称のスクリプトファイルを作成し、ファイルを読み込み、関数のテストを記述する。テスト自体は@マクロを用いると以下のように記述できる。# sumtest.jl include("sum.jl") @assert sum([0]) == 0 @assert sum([1, 2, 3]) == 6
動作テストには他にレファレンス実装を用意する方法もある。レファレンス実装とは、対象のプログラムや関数と同じ動作をするプログラムを実装することである。
例:自作関数とレファレンス関数の比較
@assert myfunc(arg1, arg2, ...) = reference(arg1, arg2,...)
プログラムをパッケージとして開発している場合には、パッケージのユニットテストを実行するのが有効である。
プログラムがデータを入力として取る場合、プロファイリングに用いるサンプルデータも用意する必要がある。このデータは現実に入力として用いられるデータに近い性質を持っていなければならない。また1回のプロファイリングに長い時間がかかる大きなサンプルデータも避けるべきである。
実用上、データの性質や規模を変えた複数のサンプルデータを用意して性能測定をすべきである。チューニングの結果、あるサンプルデータで性能が向上しても、他のサンプルデータでは著しく性能が劣化することもある。複数のサンプルデータから成るデータセットで行うベンチマークはベンチマーク・スイート( )と呼ばれる。
4.1.2 実行時間の計測
高速化したいプログラムとテストを用意したら、現在の実行時間を計測する。プロファイルとチューニングの結果、どの程度の高速化が達成できたかはこの実行時間を基準とする。
実行時間を計測するには、対象を1つの関数にまとめるのがよい。
例:ソート関数の計測*1
using Distributions xs = randn(100) @time sort(xs) @time sort(xs) @time sort(xs)
より正確に時間の統計量を計測したければ、を用いるのが望ましい。
using BenchmarkTooks @benchmark sort(xs)