今日はパフォーマンスについて質問があります。
私は (Haskell) プログラムを作成しています。プロファイリングを行ったところ、ほとんどの時間が以下の関数に費やされていることがわかりました。その目的は、リストの n 番目の要素を取得し、要素自体以外にそれを含まないリストを返すことです。私の現在の(遅い)定義は次のとおりです。
breakOn :: Int -> [a] -> (a,[a])
breakOn 1 (x:xs) = (x,xs)
breakOn n (x:xs) = (y,x:ys)
where
(y,ys) = breakOn (n-1) xs
Int
引数は (null ではない) list の長さの範囲内にあることがわかっているため、1..n
関数でエラーが発生することはありません。n
(x:xs)
しかし、ここではパフォーマンスが低下しました。私の最初の推測は、リストを別の構造に変更する必要があるということです。しかし、さまざまな構造の選択とコードのテストを開始する前に (これには多くの時間がかかります)、ここで第三者の意見を求めたいと思いました。また、私はそれを最善の方法で行っていないと確信しています。どんなポインタでも大歓迎です!
a
タイプが のインスタンスでない場合があることに注意してくださいEq
。
解決
Data.SequenceモジュールSequence
の s を使用するコードを適応させました。結果は次のとおりです。
import qualified Data.Sequence as S
breakOn :: Int -> Seq a -> (a,Seq a)
breakOn n xs = (S.index zs 0, ys <> (S.drop 1 zs))
where
(ys,zs) = S.splitAt (n-1) xs
ただし、改善の提案は引き続き受け付けます。