使用类型族更有效的类型级计算?

时间:2014-10-23 22:32:32

标签: haskell ghc functional-dependencies type-families type-level-computation

根据Monad Reader第8期的文章,我已经为" Instant Insanity"编写了类型级解决方案。使用功能依赖和类型系列拼图:

fundeps解决方案大约需要200秒。而类型族版本在大约800秒内完成。

我是否可以使用任何技术使类型系列版本更有效地运行?

1 个答案:

答案 0 :(得分:4)

我已将main的以下定义添加到您的两个代码段中,以便解决方案显示在类型错误消息中,抱怨缺少Show实例:

-- fundeps.hs
{-# OPTIONS_GHC -fcontext-stack=400 #-}
main = print $ solutions (undefined :: Cubes)

-- families-open.hs
{-# OPTIONS_GHC -ftype-function-depth=400 #-}
data Proxy a = Proxy
main = print (Proxy :: Proxy (Solutions Cubes))

并使用GHC 7.8.3进行编译以获得一些基线时间:

  • fundeps.hs:23s
  • families-open.hs:46s

我发现只是将类型系列版本转换为使用封闭类型系列(代码here)可以加快它的速度,从而将差异分开:

  • families-closed.hs:36s

我认为通过使用DataKinds(代码here)给类型系列提供严格的类型可以加快速度,但令人惊讶的是,这让我回到原点:

  • families-closed-datakinds.hs:44s

但是,至少它产生了所有四个版本中最易读的输出:

No instance for (Show
                   (Proxy
                      '['['Cube 'G 'B 'W 'R 'B 'G, 'Cube 'W 'G 'B 'W 'R 'R,
                          'Cube 'R 'W 'R 'B 'G 'R, 'Cube 'B 'R 'G 'G 'W 'W],
                        '['Cube 'G 'B 'R 'W 'B 'G, 'Cube 'R 'R 'W 'B 'G 'W,
                          'Cube 'R 'G 'B 'R 'W 'R, 'Cube 'W 'W 'G 'G 'R 'B],
                        '['Cube 'G 'W 'R 'B 'B 'G, 'Cube 'W 'B 'W 'R 'G 'R,
                          'Cube 'R 'R 'B 'G 'W 'R, 'Cube 'B 'G 'G 'W 'R 'W],
                        '['Cube 'G 'R 'W 'B 'B 'G, 'Cube 'R 'W 'B 'G 'R 'W,
                          'Cube 'R 'B 'R 'W 'G 'R, 'Cube 'W 'G 'G 'R 'W 'B],
                        '['Cube 'G 'R 'B 'B 'W 'G, 'Cube 'W 'W 'R 'G 'B 'R,
                          'Cube 'R 'B 'G 'W 'R 'R, 'Cube 'B 'G 'W 'R 'G 'W],
                        '['Cube 'G 'W 'B 'B 'R 'G, 'Cube 'R 'B 'G 'R 'W 'W,
                          'Cube 'R 'R 'W 'G 'B 'R, 'Cube 'W 'G 'R 'W 'G 'B],
                        '['Cube 'G 'B 'B 'W 'R 'G, 'Cube 'W 'R 'G 'B 'W 'R,
                          'Cube 'R 'G 'W 'R 'B 'R, 'Cube 'B 'W 'R 'G 'G 'W],
                        '['Cube 'G 'B 'B 'R 'W 'G, 'Cube 'R 'G 'R 'W 'B 'W,
                          'Cube 'R 'W 'G 'B 'R 'R, 'Cube 'W 'R 'W 'G 'G 'B]]))

因此,似乎至少可以用来加速代码的一种技术是使用封闭式系列

截至2014年12月的绩效数据更新

正如我之前评论的那样,我也在GHC 7.9开发线上尝试过这些相同的程序,并发现了一些严重的性能回归。这导致了a GHC bug ticket现在已经解决了惊人的结果:涉及类型系列的所有三个解决方案在即将到来的GHC 7.10发布上明显更快地进行了测试!

新的时间数字(截至GHC a225c70)如下:

  • families-open.hs:7s
  • families-closed.hs:6.5s
  • families-closed-datakinds.hs:7.5s

鉴于我在没有任何严谨的情况下运行这些测试,上述三个时间应该被认为是相等的,这意味着我肯定会选择封闭式系列+数据线方法打字并产生最好的输出。