0

以下は機能しますが、非常に非効率的です。
原因はリスト連結の使用にあると思われます。

import Control.Parallel.Strategies   (runEval, rpar)
import Data.Text                     (Text)
import qualified Data.Text.IO as T   (writeFile)
import Text.InterpolatedString.Perl6 (qq)
-- random data imports
import Crypto.Random.AESCtr          (makeSystem)
import System.Random                 (split, randomR, randomRs)


-- |This function picks a random element from a list
-- choose :: RandomGen g => g      -- ^ random generator
--                       -> [a]    -- ^ list to be taken from
--                       -> (a, g) -- ^ random pick
choose g lst = let ra = randomR (0::Int, length lst -1) g
               in  (lst !! fst ra, snd ra)

-- |This function generates a set of french SSN numbers
-- http://mon-convertisseur.fr/calculateur-cle-numero-securite-sociale.php
-- sans check digits
-- genFrSSN :: RandomGen g => g      -- ^ random generator
--                         -> [Text] -- ^ list of data
genFrSSN g = [fin] ++ genFrSSN g5
  where
    (sex, g1)    = choose g [1..2]
    (yBirth, g2) = choose g1 [70..99]
    (mBirth, g3) = choose g2 [10..12]
    (depart, g4) = choose g3 [21..95]
    commune      = 999
    (numOrd, g5) = randomR (100::Int, 300) g4
    -- using interpolatedstring-perl6
    -- because for some other generator I may have not have only Int data
    fin          = [qq|$sex$yBirth$mBirth$depart$commune$numOrd|] :: Text

私が書き直したもの

genFrSSN g = runEval $ do 
    a <- rpar [fin]
    b <- rpar $ genFrSSN (snd sx)
    return (a ++ b)
  where
    sx           = split g
    (sex, g1)    = choose (fst sx) [1..2]
    (yBirth, g2) = choose g1 [70..99]
    (mBirth, g3) = choose g2 [10..12]
    (depart, g4) = choose g3 [21..95]
    commune      = 999
    (numOrd, _) = randomR (100::Int, 300) g4
    fin          = [qq|$sex$yBirth$mBirth$depart$commune$numOrd|] :: Text

しかし、その後、低くなる代わりに、単にメモリが不足し、CPU が過剰に使用されます。ジェネレーターは、可変数の要素を取得する無限リストを提供することになっています。
複数のデータを入力するときに便利な[Char]があるのでリストを使っています

まず、どうすれば (++) を取り除くことができますか? そして第二に、批判してください。

4

1 に答える 1

2

1

++問題ありません。とにかく、単一の要素リストを先頭に追加するためにのみ使用しているようです。

2

randomR (70,99)の代わりになぜではないのchoose g [70..99]ですか?それはただの無駄な非効率です。型の値の範囲から選択したいときはいつでもそうすることができますEnum。しかし、一般的なケースでは、リストの代わりにO(1)を使用chooseしたデータ構造で機能させることによってのみ、(本当に必要な場合に)の効率を向上させることができます。length(!!)

3

問題は並列評価にあります。私はそのようなことに十分に精通していませんが、-threadedオプションなしでプログラムをコンパイルしようとすると、メモリが少なく、一定のメモリですばやく実行されます。を使用-threadedすると、メモリ不足エラーが発生します。理由はわかりませんが、そもそもこれを並列化する必要はないと思います。タスクは本質的に並列ではありません。

于 2013-09-05T09:08:44.097 に答える