謝罪これがあまりにも具体的な場合は、私はここに新しいと妥当なものが正確ではない。私は何時間もこの問題に対して頭を打つことを何もしてこなかった。次のコードは、私の競合プログラミング問題の実装です。ハスケルボトムアップDP空間リーク
これは、DPテーブルの各行を以前の解決策の折り目を使って生成するボトムアップの動的プログラミングソリューションのように機能するということです。理論的には、GHCはテーブルのすべての古い行を最適化できるはずです。しかし、約l = 2000
とlength f = 5000
で適度に大きな入力にこのプログラムを実行している、私はこれを取得:ピーク時にメモリの878メガバイトを使用しています
> time ./E < E.in
0
1.98user 0.12system 0:02.10elapsed 99%CPU (0avgtext+0avgdata 878488maxresident)k
0inputs+0outputs (0major+219024minor)pagefaults 0swaps
!私が生成しているテーブルはたったの10,000行で、理論的には一度に1行しか必要ありません!これは何らかの形のサンクの漏れまたは他のスペースリークであることは明らかです。プロファイリングでは、run
が実行時間とメモリの合計の99%を消費していることがわかります。さらに調査すると、その98%がzipWith
コールにあったことが示されました。
> time ./E < E.in
0
1.39user 0.08system 0:01.48elapsed 99%CPU (0avgtext+0avgdata 531400maxresident)k
0inputs+0outputs (0major+132239minor)pagefaults 0swaps
メモリだけで70%の実行時間、および60%です:興味深いことに、私のカスタムでzipWith min
への呼び出しを置き換えるzipMin
機能が大幅に改善を生成します!私はこの仕事をするためにあらゆる種類の試みをしました。私は(++)
が一般的に悪い考えであることを知っているので、run
のリストをData.Sequence.Seq Int
と置き換えました。遅くなり、より多くのメモリを使用しました。私はハスケルで特に経験はありませんが、ここで私の気分は終わりです。私はこの問題に対する答えがまだあることを確信していますが、私はそれを見つけることができるようにハスケルにはあまりにも新しいです。
あなたが提供できるヘルプは非常に高く評価されています。私は間違ったやり方、将来の診断方法、そしてそれを修正する方法を正確に説明することが大好きです。
ありがとうございます。
EDIT:スティーブンの優秀な助言に従い、アンボクシングと私のリストを交換した後
はパフォーマンスがあるベクトル...ええと... signficantlyが向上:
> time ./E < E.in
0
0.01user 0.00system 0:00.02elapsed 80%CPU (0avgtext+0avgdata 5000maxresident)k
24inputs+0outputs (0major+512minor)pagefaults 0swaps
クイック返信いただきありがとうございます。これは素晴らしいと明確な説明です。私はいくつかのフォローアップの質問を持っています: 1.コンパイラがこれを最適化できないのはなぜですか?それは熟したターゲットのようです。 2.標準配布でこれを行う実際的な方法はありますか?私はこのソリューションが満足のいくものだと思っていますが、残念なことに競争サーバーはベクターパッケージをサポートしていません。 もう一度ありがとうございます。 – Gozz
これは、かなり複雑な最適化レベルになります。厳密性の分析フェーズがありますが、チューリングの完全性のために必ずしも正しいとは限りません。あなたは厳密なリストパッケージが利用可能であることを確認するか、またはあなた自身の厳密なリストタイプ 'data SList a = Cons!a!(SList a)|頭が強制されるならば、リスト全体を強制する "Nil'。 deepseqが利用可能かどうかを確認することもできます。これを使用して、通常のリストを完全に評価することができます。 –
非常に興味深い、ありがとうございました。これはちょっとしたハックですが、私はData.IntMap.Strictが実際にこのコンペで十分速いことがわかりました。あなたの助けをもう一度ありがとう。 – Gozz