我一直在试验用下面的Haskell代码:调整一个numItems和numLists当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: 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秒内三亿个元素的三次统计。这大约每秒2000万个元素。这听起来对你来说效率低下吗? (然而,你确实有一个巨大的空间泄露,但这是另一回事,这会帮助你解决这个问题) –
虽然你可能是对的关于这一点,我的问题的主要目的是了解代码是否可以在wrt上得到改进。性能。 – toeplitz
我想upvote这个评论为“你有一个巨大的空间泄漏,但是...” – epsilonhalbe