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 回答