[過去ログ] 関数型プログラミング言語Haskell Part7 (1001レス)
前次1-
抽出解除 レス栞

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
885
(3): 2007/09/21(金)12:10 AAS
>>884
確かにそうだ。最悪O(n^2)になるな。
でも、中間リストを作ることが直接の原因ではない。
実際、正確評価ならelts_lt_xとelts_greq_xを作り終えた時点で引数のxsはGCできる。
遅延評価だとこれが上手くいかなくて、逆順にソートされたリストが渡される最悪のケースでO(n^2)になる。
時間的には同じ最悪のケースでも、入力が正順にソートされていた場合はO(n)なんだが。

汚い方法だけど、seqを使って評価順を入れ替えることでO(n)になる。
qsort [] = []
qsort (x:xs) = length elts_lt_x `seq` length elts_greq_x `seq`
  qsort elts_lt_x ++ [x] ++ qsort elts_greq_x
省3
886
(5): 2007/09/21(金)12:47 AAS
プロファイル取って調べてみた。数字はtotal allocにqsortの%allocをかけたもの。左の数字は要素数。

>>881とランダム要素のリスト
800 : 380003.544
1600: 873076.32
2400: 1296538.048
3200: 1816425.728
4000: 2399276.16

>>885とランダム要素のリスト
800 : 400965.324
1600: 1040519.448
省16
892: 2007/09/21(金)18:05 AAS
>>891
>HaskellのGCって、いらなくなった瞬間に動くものだったんだな。
デフォルトだと確保エリアの大きさは256kらしいから、第0世代のGCは頻繁に起こるんだろう。

>と書くといいかなと思ったり。
それだとリストの先頭しかeagerに評価されないから、
[99, 100, 97, 98, 95, 96, ..., 4, 1]
みたいなリストが入力だとO(n^2)になる。
リストを最後まで評価させるために>>885ではlengthを使ってる。
895
(2): 2007/09/21(金)20:23 AAS
>>885
このコードが理解できない初心者のために、教えてください。
seqは遅延評価をしないための関数のようですが、lengthは何のためにあるのでしょうか。
あとseqは2項演算子として使うのが普通なのですか。
qsort [] = []
qsort (x:xs) = seq (length elts_lt_x) (seq (length elts_greq_x) (qsort elts_lt_x ++ [x] ++ qsort elts_greq_x))
 where
  elts_lt_x = [y | y <- xs, y < x]
  elts_greq_x = [y | y <- xs, y >= x]
と買いても間違いではない?
省4
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.038s