Optimization 如果我';我在Haskell/GHC中使用unbox类型(比如Int#)?

Optimization 如果我';我在Haskell/GHC中使用unbox类型(比如Int#)?,optimization,haskell,ghc,unboxing,brainfuck,Optimization,Haskell,Ghc,Unboxing,Brainfuck,我试图写一个小脚本来解析和执行Brainfuck代码,为了理解GHC的优化选项,我试图优化代码,以便更快一点,理解那里发生了什么 在这些部分中,有一部分是BF代码的内部表示,我为此使用了一个特殊的数据类型。以下是源代码,包括两个进行转换的函数: data BFinstruction = AdjustValue Int | MovePointer Int | GetChar | PutChar | Loop BFcode deriving (Eq) type BFcode

我试图写一个小脚本来解析和执行Brainfuck代码,为了理解GHC的优化选项,我试图优化代码,以便更快一点,理解那里发生了什么

在这些部分中,有一部分是BF代码的内部表示,我为此使用了一个特殊的数据类型。以下是源代码,包括两个进行转换的函数:

data BFinstruction
  = AdjustValue Int
  | MovePointer Int
  | GetChar
  | PutChar
  | Loop BFcode
  deriving (Eq)

type BFcode = [BFinstruction]

unsafeCompileBrainfuck :: String -> BFcode
unsafeCompileBrainfuck = fst . parse [] where
  -- arguments: input string, built code; output: output code, rest of input
  parse :: BFcode -> String -> (BFcode,String)
  parse c ('+':s) = parse (AdjustValue   1 :c) s
  parse c ('-':s) = parse (AdjustValue (-1):c) s
  parse c ('>':s) = parse (MovePointer   1 :c) s
  parse c ('<':s) = parse (MovePointer (-1):c) s
  parse c ('.':s) = parse (PutChar         :c) s
  parse c (',':s) = parse (GetChar         :c) s
  parse c (']':s) = (reverse c, s)
  parse c ('[':s) = parse (Loop l          :c) s' where (l,s') = parse [] s
  parse c []      = (reverse c ,"")
  parse c ( _ :s) = parse                   c  s

simplifyBrainfuck :: BFcode -> BFcode
simplifyBrainfuck ((AdjustValue x):(AdjustValue y):zs) = if x + y /= 0
  then simplifyBrainfuck (AdjustValue (x + y):zs)
  else simplifyBrainfuck zs
simplifyBrainfuck ((MovePointer x):(MovePointer y):zs) = if x + y /= 0
  then simplifyBrainfuck (MovePointer (x + y):zs)
  else simplifyBrainfuck zs
simplifyBrainfuck (x                              :zs) = x: simplifyBrainfuck zs
simplifyBrainfuck []                                   = []

这将把装箱的
Int
类型转换为未装箱的原始
Int
类型,这是GHc的一个实现细节。正如我所读到的,这个选项只有在少数情况下是好的,所以我想问一下,如果我想执行这种优化,我必须注意哪些事情。我的目标是允许使用Haskell的优点执行BF代码—惰性(我想归档,代码可能只在需要时保存在内存中)和易用性

这真的有必要吗?您是否在使用此代码时遇到性能问题,您认为这是装箱值的结果?如果没有,不用麻烦了

如果您确实认为是这种情况,那么似乎可以以方便的列表格式提供必要的限制


要点似乎是,多态函数或名称与未绑定类型之间的任何类型的交互(未被编译器拒绝)都可能导致严重的空间泄漏。另外,如果不尝试它,我怀疑您将不会在溢出的情况下抛出异常,例如,因此假设您应该自己检测这种情况。一个简单的测试可以验证这是否真的是这样。

对我来说,这看起来真的是一个过早的优化。当您有大量的
bf指令
s时,“解包”最有用。我怀疑你是否有足够的脑力代码使它值得。我同意Gian的观点,它应该足够简单,可以测试,所以先这样做


在任何情况下,对于解包的值要注意的一点是,您不希望编译器必须重新编译它们。您应该可以使用数字运算,但除此之外,您必须仔细查看您正在使用的函数,以查看是否曾经将未打包的值用作非严格参数。确保的唯一方法是查看核心或接口文件,看看哪些参数严格,哪些不严格。和往常一样,确保至少使用“-O”进行编译。

只是想知道有多少人会将这种攻击性贴上标签,即使BrainF**k是一种实际的语言…+1。如果我需要非固定值,那是因为我有很多。如果我有很多,它们将在一个向量中。然后我将使用Data.Vector.unbox。
data BFinstruction -- BangPatterns
  = AdjustValue {-# UNPACK #-} !Int
  | MovePointer {-# UNPACK #-} !Int
  | GetChar
  | PutChar
  | Loop BFcode
  deriving (Eq)