haskell - 在 Haskell 中程序生成大量值列表——最惯用的方法?内存管理?

标签 haskell idioms

我有一个函数,它接受一系列随机数/浮点数,并使用它们来生成一个值/结构(即,随机速度和一个球被抛出的点的位置,并输出它着陆的坐标) .我需要连续生成数千个。

我实现一切的方式是每个计算都接受一个 stdGen,使用它来生成几个数字,然后传递一个新的 stdGen 以允许它链接到另一个。

为了对 10000 个项目执行此操作,我从 generate_item n 制作了一个列表基本上输出一个 (value,gen)元组(该值是我要计算的值),其中 gen 的值是从 generate_item n-1 中获取值所涉及的计算中递归输出的 stdGen

然而,这个程序似乎在大约一千个结果时爬行速度慢得不切实际。而且似乎绝对不可扩展。这可能与我存储所有 generate_item 的事实有关吗?结果在内存中?

或者在 Haskell 中使用 Monads 或其他比我上面描述的方法来解决这个问题的方法更符合习惯吗?

请注意,即使在 ruby​​ 和 python 等高级脚本语言中,从随机值生成算法的代码也会在几秒钟内生成 10k;这些计算并不密集。

代码

-- helper functions that take in StdGen and return (Result,new StdGen)
plum_radius :: StdGen -> (Float,StdGen)
unitpoint   :: Float -> StdGen -> ((Float,Float,Float),StdGen)
plum_speed  :: Float -> StdGen -> (Float,StdGen)

-- The overall calculation of the value
plum_point  :: StdGen -> (((Float,Float,Float),(Float,Float,Float)),StdGen)
plum_point gen  = (((px,py,pz),(vx,vy,vz)),gen_out)
  where
    (r, gen2)         = plum_radius gen
    ((px,py,pz),gen3) = unitpoint r gen2
    (s, gen4)         = plum_speed r gen3
    ((vx,vy,vz),gen5) = unitpoint s gen4
    gen_out           = gen5

-- Turning it into some kind of list
plum_data_list  :: StdGen -> Int -> (((Float,Float,Float),(Float,Float,Float)),StdGen)
plum_data_list seed_gen 0  = plum_point seed_gen
plum_data_list seed_gen i  = plum_point gen2
  where
    (_,gen2)  = plum_data_list seed_gen (i-1)

-- Getting 100 results
main = do
  gen <- getStdGen
  let data_list = map (plum_data_list gen) [1..100]
  putStrLn List.intercalate " " (map show data_list)

最佳答案

考虑只使用mersenne-twister 和vector-random package ,它经过专门优化以生成大量高质量的随机数据。

列表不适合分配大量数据 - 最好使用打包表示 - 除非您正在流式传输。

关于haskell - 在 Haskell 中程序生成大量值列表——最惯用的方法?内存管理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15266920/

相关文章:

haskell - 是否有一个标准的 Haskell 函数在函数前面附加一个额外的参数

haskell - haskell 的战舰(初级)

python - 惯用的 Python : `in` keyword on literal

c++ - C++ 中的 "sentry object"是什么?

python - Python 的 KeyError 的惯用 Clojure 版本

haskell - 如何使用 map 和过滤器实现列表理解?

haskell - Haskell 中惯用的有状态循环

Haskell 列表 monad 循环

swift - 惯用的 Swift 多重通知?

java - Java中的LBYL与EAFP?