以下工作但非常低效 我怀疑这是我使用列表连接的原因。
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]在有多个数据输入时很方便
首先,如何摆脱(++)?其次请批评。
答案 0 :(得分:2)
<强> 1 强>
++
不是问题。看起来你只是用它来预先添加单个元素列表。
<强> 2 强>
为什么不只是randomR (70,99)
而不是choose g [70..99]
?这只是无用的低效率。只要您想从Enum
类型中选择一系列值,就可以执行此操作。但是在一般情况下,您只能通过使用O(1)choose
和length
来处理数据结构,从而提高(!!)
(当您真正需要它时)的效率列表。
第3 强>
问题在于并行评估。我不熟悉那些东西可以帮助你,但是当我尝试在没有-threaded
选项的情况下编译你的程序时,它运行得很快并且内存很低,常量很低。使用-threaded
,我收到内存不足错误。我不知道为什么会这样,但我认为你不应该首先将这些东西并行化。这项任务本身并不平行。