【发布时间】:2014-02-08 18:47:35
【问题描述】:
我一直在试验以下 Haskell 代码:
data Foo = Foo
{ fooMin :: Float
, fooMax :: Float
, fooSum :: Float
} deriving Show
getLocalFoo :: [Float] -> Foo
getLocalFoo x = Foo a b c
where
a = minimum x
b = maximum x
c = sum x
getGlobalFoo :: [Foo] -> Foo
getGlobalFoo x = Foo a b c
where
a = minimum $ fmap fooMin x
b = maximum $ fmap fooMax x
c = sum $ fmap fooSum x
main :: IO()
main = do
let numItems = 2000
let numLists = 100000
putStrLn $ "numItems: " ++ show numItems
putStrLn $ "numLists: " ++ show numLists
-- Create an infinite list of lists of floats, x is [[Float]]
let x = take numLists $ repeat [1.0 .. numItems]
-- Print two first elements of each item
print $ take 2 (map (take 2) x)
-- First calculate local min/max/sum for each float list
-- then calculate the global min/max/sum based on the results.
print . getGlobalFoo $ fmap getLocalFoo x
并在调整 numItems 和 numLists 时依次测试运行时:
小尺寸:
numItems: 4.0
numLists: 2
[[1.0,2.0],[1.0,2.0]]
Foo {fooMin = 1.0, fooMax = 4.0, fooSum = 20.0}
real 0m0.005s
user 0m0.004s
sys 0m0.001s
大尺寸:
numItems: 2000.0
numLists: 100000
[[1.0,2.0],[1.0,2.0]]
Foo {fooMin = 1.0, fooMax = 2000.0, fooSum = 1.9999036e11}
real 0m33.116s
user 0m33.005s
sys 0m0.109s
我在没有考虑性能的情况下以我认为直观和幼稚的方式编写了此代码,但是我担心这远非最佳代码,因为我实际上可能会以比必要的方式更多次地折叠列表?
谁能建议更好地实施这个测试?
【问题讨论】:
-
您在 33 秒内计算了两亿个元素的三个统计数据。这大约是每秒每个统计信息的两千万个元素。对你来说这听起来效率低下吗? (但是你确实有大量的空间泄漏,但那是另一回事。这将帮助你解决这个问题haskellforall.com/2013/08/composable-streaming-folds.html)
-
虽然您对此可能是对的,但我提出这个问题的主要目的是了解代码是否可以在 wrt 上进行改进。性能。
-
我想为“你确实有大量空间泄漏但是......”的评论投赞成票
标签: haskell