English 中文(简体)
GHC提出的合作守则动议
原标题:Coaxing loop-invariant code motion out of GHC

我在为全球健康中心的低水平体体体体能优化而努力。 我的方案包含一些从事计算数字的假体。 实际数据在其他数据结构中作了总结,该方案被细分为“流动控制功能”和“计算功能”,因此有些数据结构领域最终被内部内部读。 我希望格奥尔卡将那些读物的人移出内.。 这里是该守则的简化版本,以显示其进展。

data D = D !Double !C
data C = C Double

-- This function is called in every loop iteration.
-- Parameter  c  is loop-invariant.
exampleLoopBody i a c =
  case c of C b -> a + b * fromIntegral i

-- The body of this function is a counted loop that should be optimized
foo x =
  case x
  of D acc0 c ->
    let loop i acc =
          if i > 100
          then acc
          else loop (i+1) (exampleLoopBody i acc c)
    in loop 0 acc0

每一处孔径流体评价C b c条,但这种计算是多余的,因为<条码>c是 lo。 我可以把多余的个案表述放在外面,使GHC解除危险:

foo x =
  case x
  of D acc0 c ->
    case c             -- This case statement inserted for optimization purposes
    of C b -> b `seq`  -- It will read  b  outside of the loop
      let loop i acc =
           if i > 100
           then acc
           else loop (i+1) (exampleLoopBody i acc c)
      in loop 0 acc0

网上编辑<代码>exampleLoopBody。 其后,内案陈述是多余的,删除:

foo x =
  case x
  of D acc0 c ->
    case c
    of C b -> b `seq`
      let loop i acc =
            if i > 100
            then acc
            else loop (i+1) (acc + b * fromIntegral i) -- The inlined case expression disappears
      in loop 0 acc0

<代码>seq 的目的是确保案件表述不成死亡代码。 www.un.org/Depts/DGACM/index_french.htm http://code>b。 GHC指出,由于对<代码>b进行了计算,因此在机体内重新使用这一数值是有益的。

现在的问题是: 我确实希望所有相关的数据领域都严格。 如果在数据定义中加上严格的说明,就如此,

data C = C !Double

然后seq and case c of C b 只要涉及GHC,就没有效力。 GHC删除了这些内容,我这样做:

foo x =
  case x
  of D acc0 c ->
    let loop i acc =
          if i > 100
          then acc
          else loop (i+1) (case c of C b -> acc + b * fromIntegral i) -- Evaluate the case in every iteration
     in loop 0 acc0

这部法典在每部电传中都评价了C bcase c,这正是我试图避免的。

如果我可以依靠<代码>seq,我不知道如何将<条码>b<>/条码>强加于人,在体外计算。 我是否可在此案中使用某种骗子?

问题回答

您可尝试重新提出论点,将左轮变量部分移入一个lam子:

-- note the order of the arguments changed
exampleLoopBody (C b) =
  i a -> a + b * fromIntegral i

foo (D acc0 c) =
    let
       loopBody = exampleLoopBody c 
       loop i acc =
          if i > 100
         then acc
         else loop (i+1) (loopBody i acc)
   in loop 0 acc0

而且,这部法典目前还形成了大量未评价的表述,因此,你可能希望每次通过该循环强行使用累积器参数。

这基本上与全部理由(<代码>新式)一样,用文字表述。 Just change data C = C !Double to newtype C = C Double and written the naive edition of the Code. 将删除所有<条码>>>>关于<条码>值的表述。 顺便提一下,你在以下例子中采用了守则模式:

case foo of
    D acc0 c -> case c of
        C b -> ...

可以更简明扼要地撰写:

case foo of
    D acc0 (C b) -> ...




相关问题
Euler Problem in Haskell -- Can Someone Spot My Error

I m trying my hand at Euler Problem 4 in Haskell. It asks for that largest palindrome formed by multiplying two three-digit numbers. The problem was simple enough, and I thought my Haskell-fu was up ...

How does foldr work?

Can anybody explain how does foldr work? Take these examples: Prelude> foldr (-) 54 [10, 11] 53 Prelude> foldr (x y -> (x+y)/2) 54 [12, 4, 10, 6] 12.0 I am confused about these executions....

Efficient queue in Haskell

How can I efficiently implement a list data structure where I can have 2 views to the head and end of the list, that always point to a head a tail of a list without expensive calls to reverse. i.e: ...

Problem detecting cyclic numbers in Haskell

I am doing problem 61 at project Euler and came up with the following code (to test the case they give): p3 n = n*(n+1) `div` 2 p4 n = n*n p5 n = n*(3*n -1) `div` 2 p6 n = n*(2*n -1) p7 n = n*(5*n -3)...

Ways to get the middle of a list in Haskell?

I ve just started learning about Functional Programming, using Haskel. I m slowly getting through Erik Meijer s lectures on Channel 9 (I ve watched the first 4 so far) and in the 4th video Erik ...

haskell grouping problem

group :: Ord a => [(a, [b])] -> [(a, [b])] I want to look up all pairs that have the same fst, and merge them, by appending all the list of bs together where they have the same a and discarding ...

Closest equivalent to subprocess.communicate in Haskell

I want to do a popen() / python s subprocess.communicate from Haskell - start a program, give it stdin, and get its stdout/stderr. What s the most direct / Haskellish way to do this?

热门标签