私は小さなテストフレームワークを持っています。次のループを実行します。runhaskellのスピードアップ
小さなHaskellソースファイルを生成します。
runhaskell
でこれを実行します。プログラムはさまざまなディスクファイルを生成します。作成したばかりのディスクファイルを処理します。
これは数十回起こります。 runhaskell
がプログラムの実行時間の大半を占めていることが判明しました。
一方で、runhaskell
がディスクからファイルをロードし、それをトークン化し、解析し、依存性分析を行い、ディスクから20KB以上のテキストをロードし、トークン化し、完全な型推論を実行し、チェックするコンパイルされたマシンコードとのリンク、インタープリターでの実行、壁の時間の2秒以内のすべては、あなたがそれについて考えるとき、実際にかなり印象的です。一方、私はまだそれをより速くしたいです。 ;-)
テスター(上記のループを実行するプログラム)をコンパイルすると、小さなパフォーマンスの違いが生じました。スクリプトがリンクする20KBのライブラリコードをコンパイルすると、はるかに目立った改善が得られました。しかし、呼び出しごとに約1秒かかります。runhaskell
。
生成されたHaskellファイルは、それぞれ1KBを少し上回りますが、ファイルの一部だけが実際に変更されます。おそらくファイルをコンパイルし、GHCの-e
スイッチを使用する方が速いでしょうか?
また、これを遅くしている多くのOSプロセスを繰り返し作成して破壊するオーバーヘッドがありますか? runhaskell
を呼び出すたびに、OSはシステムの検索パスを探索し、必要なバイナリファイルを探し出し、メモリにロードします(これは既にディスクキャッシュにありますか?)、DLLとリンクして起動します。 OSプロセスを絶えず作成して破壊するのではなく、GHCの1つのインスタンスを(簡単に)実行できる方法がありますか?
最終的には、常にGHC APIがあると思います。しかし、私が理解しているように、これは悪夢の日には使いにくく、文書化されておらず、GHCの小さな点での急進的な変化に敏感です。私が実行しようとしている作業は非常に単純なものなので、必要以上に複雑なものにしたくないのです。
提案?
更新:はGHC -e
への切り替え(すなわち、今すべてが実行されて一つの式を除いてコンパイルされている)は測定の性能差を作りません。この時点で、すべてのOSオーバーヘッドであることは明らかです。私は多分テスターからGHCiにパイプを作成して、ただ一つのOSプロセスを利用できるかどうか疑問に思っています...
あなたの全体のワークフローは正確にパフォーマンスを重視していませんか?なぜHaskellのコードを作成しなければならないのですか? – leftaroundabout
明らかにGHCデーモンが必要です! :p(ブート中にgrepを継続的に呼び出すなどのオーバーヘッドを避けるためにgrepデーモンを作成することについて冗談を言っていた人もいます) – ivanm
+1で正当化され、正しく実行された最適化の試行。 – delnan