私はリストをシャッフルするためにList.permuteを使った最近Fisher-Yates shuffleを実装しました。リストのサイズが大きくなるにつれ、パフォーマンスが大幅に低下しました。私はこれが、アルゴリズムが配列上で動作していると仮定している間、permuteはO(n)であるインデックスによってリスト要素にアクセスしていなければならないという事実によると思われる。List.permuteのパフォーマンス
let permute i max = max - i - 1
let test = [ 0 .. 10000 ]
let rev1 list =
let perm i = permute i (List.length list)
List.permute perm list
let rev2 list =
let array = List.toArray list
let perm i = permute i (Array.length array)
Array.permute perm array |> Array.toList
I:
これを確認するために、私は、リストに直接取り組んで比較し、リストに戻る配列にリストを形質転換し、その要素を逆にリストに順列を適用試しrev1 test;;
Real: 00:00:00.283, CPU: 00:00:00.265, GC gen0: 0, gen1: 0, gen2: 0
rev2 test;;
Real: 00:00:00.003, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
私の質問は以下の通りです:私の仮定を確認する傾向があり、次の結果、取得
1する)List.permuteは、パフォーマンスレアのために避けるべきです息子?また、関連して、List.permuteの実装が自動的にシーンの背後にあるArrayへの変換を行うべきではありませんか?
2)配列を使用する以外に、このタイプの作業、つまり要素のシャッフルに適したより機能的な方法/データ構造がありますか?または、これは単にArrayが使用する正しいデータ構造体であるという問題ですか?
良い質問と優秀な回答です。時には多くのことを学ぶことがあります –