【问题标题】:Speed Up Checking for Equality in Haskell加快 Haskell 中的相等性检查
【发布时间】:2013-04-07 01:51:06
【问题描述】:

是否可以加快(或者在我的函数的情况下,删除)Haskell 中的相等性检查?我有一个函数可以总结一个代理的所有交互,其中交互是在两个代理之间。要对交互进行求和,首先必须检查代理是否等于交互中的第一个或第二个代理,然后对其求和。检查相等性几乎占用了我的程序运行时间的一半。

sumAgent :: [Interaction] -> Agent -> Int
sumAgent xs agent = foldr (\x acc -> acc + sumInteraction agent x) 0 xs

-- Use this in a map call of sumAgent to return the sums of a specific agent
sumInteraction :: Agent -> Interaction  -> Int
sumInteraction agent (Interaction a1 a2 xs )
    | (==) agent a1 = sum $ map fst scores
    | (==) agent a2 = sum $ map snd scores
    | otherwise = 0
    where scores = map score xs

是否可以通过使用 c 函数或仅检查部分代理的相等性来删除相等性检查或加速它? Eq 的实现是:

  data Agent = Agent {
                function::[(Bool,Bool)] -> Bool,
                name::String,
                position::(Int,Int),
                dna::DNA
               }
 instance Eq Agent where
        (==) a1 a2 = position a1 == position a2

【问题讨论】:

  • 您提供的信息不足,无法回答您的问题。 position 可能是一个昂贵的计算以及记录获取器。还要考虑重构算法和数据结构。维护每个代理的事件交互列表可能比每次需要聚合代理的交互时过滤常见的交互列表更便宜。
  • 另外,当你想估计性能时,确保你编译带有-O2标志的程序。
  • 顺便说一下,你总是可以在参数之间放置中缀运算符:| agent == a1 = ..., a1 == a2 = pos...
  • @leventov,只需-O 就足够了。我一直认为-O2 的意思是“优化更多”,但实际上它的意思是“做一些实验性优化,可能会意外地让你的代码变慢”。
  • @leventov,如果您不检查自己的特定程序,使用哪个是个人喜好问题(但 -O 是 cabal 在构建库时使用的,并且具有最稳定的和可靠的代码改进优化)。我总是很困惑为什么会有不同的级别——为什么我不想优化更多呢?这就是为什么。

标签: haskell optimization profiling


【解决方案1】:

你怎么知道平等花费了一半的时间?我猜你最有可能通过使用严格和未装箱的对获得性能优势:

 data Pair = P {-# UNPACK #-} !Int {-# UNPACK #-} !Int
 data Agent = Agent {
            function::[(Bool,Bool)] -> Bool,
            name::String,
            position:: {-# UNPACK #-} !Pair Int Int,
            dna::DNA
           }

这样您将避免额外的间接性,并可能获得更好的缓存行为。

【讨论】:

    猜你喜欢
    • 2011-02-10
    • 1970-01-01
    • 2015-11-23
    • 2012-01-10
    • 2016-03-18
    • 2010-12-07
    • 2015-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多