Haskell中的隐式模式匹配

2 performance haskell pattern-matching

是否应该预期这两者之间的性能差异empty,还是仅仅是风格偏好的问题?

foo list = case list of
   []      -> True
   (_ : _) -> False

bar list = case list of
   (_ : _) -> False
   _       -> True
Run Code Online (Sandbox Code Playgroud)

jbe*_*man 12

一般来说,你不应该期望性能可以通过简单的摆弄与你所询问的模式之间的变化来预测,并且通常可以期望生成的代码是相同的.

但实际检查的方法是使用标准来查看核心和/或基准.在这种情况下,生成的代码是相同的,实际上GHC似乎实际上将它们组合在一起:

我用上面编译了上面的代码片段

ghc -Wall -O2 -ddump-to-file -ddump-simpl -dsuppress-module-prefixes -dsuppress-uniques -fforce-recomp  YourCode.hs
Run Code Online (Sandbox Code Playgroud)

我们看到了这个核心:

foo :: forall t. [t] -> Bool
[GblId,
 Arity=1,
 Caf=NoCafRefs,
 Str=DmdType <S,1*U>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)
         Tmpl= \ (@ t) (list [Occ=Once!] :: [t]) ->
                 case list of _ [Occ=Dead] {
                   [] -> True;
                   : _ [Occ=Dead] _ [Occ=Dead] -> False
                 }}]
foo =
  \ (@ t) (list :: [t]) ->
    case list of _ [Occ=Dead] {
      [] -> True;
      : ds ds1 -> False
    }

-- RHS size: {terms: 1, types: 0, coercions: 0}
bar :: forall t. [t] -> Bool
[GblId,
 Arity=1,
 Caf=NoCafRefs,
 Str=DmdType <S,1*U>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)
         Tmpl= \ (@ t) (list [Occ=Once!] :: [t]) ->
                 case list of _ [Occ=Dead] {
                   [] -> True;
                   : _ [Occ=Dead] _ [Occ=Dead] -> False
                 }}]
bar = foo
Run Code Online (Sandbox Code Playgroud)

我认为这些Tmpl东西是在其他模块中内联的原始实现,但我不确定.

  • 在你的第一句话中,"[不要期望性能可以预测地改变"和"期望生成的代码是相同的"似乎是不一致的:当然"我希望性能不会改变"是一个预测! (3认同)