没有HasCallStack时,errorWithoutStackTrace是否会比错误更快?

时间:2019-08-14 10:04:46

标签: performance haskell

我注意到基本软件包使用errorWithoutStackTrace来实现许多功能。以下两个定义之间在性能上有什么不同吗?

head :: [a] -> a
head (x:_) = x
head [] = errorWithoutStackTrace ("Prelude.head: empty list")

head :: [a] -> a
head (x:_) = x
head [] = withFrozenCallStack $ error ("Prelude.head: empty list")

1 个答案:

答案 0 :(得分:2)

error意味着发生了一件不好的事情,因此对于大多数(即使不是全部)目的,它有多快也没关系,因为它表明程序无法正常工作


也就是说,快速浏览一下代码足以合理地猜测errorerrorWithoutStackTrace做的工作要严格得多(并且在{的基础上增加了withFrozenCallStack {1}}代码的变体。读者可以自己确定是否使用基准测试。

这是errorerror的定义:

https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Err.html#error

errorWithoutStackTrace

现在,这两个内部函数的定义如下:

error s = raise# (errorCallWithCallStackException s ?callStack)

errorWithoutStackTrace s = raise# (errorCallException s)

请注意,两者本质上都执行errorCallException :: String -> SomeException errorCallException s = toException (ErrorCall s) errorCallWithCallStackException :: String -> CallStack -> SomeException errorCallWithCallStackException s stk = unsafeDupablePerformIO $ do ... return $ toException (ErrorCallWithLocation s stack) ,但是toException (something s)还有很多代码来处理堆栈(在“ errorCallWithCallStackException”中)。