Haskell 为什么是;“阴谋集团建造”;与“相比,速度太慢了”;使“成为”;?

Haskell 为什么是;“阴谋集团建造”;与“相比,速度太慢了”;使“成为”;?,haskell,build,cabal,Haskell,Build,Cabal,如果我有一个包含多个可执行文件的包,我最初使用cabalbuild构建它。现在我更改一个只影响一个可执行文件的文件,cabal似乎需要大约一两秒钟的时间来检查每个可执行文件是否受到影响。另一方面,make,给定相等数量的可执行文件和源文件,将在几分之一秒内确定需要重新编译的内容。为什么会有如此巨大的差异?有什么原因吗,阴谋集团不能建立自己版本的makefile并从那里开始吗?免责声明:我对Haskell或make内部结构不够熟悉,无法给出技术细节,但一些网络搜索确实提供了一些与我的建议一致的见解

如果我有一个包含多个可执行文件的包,我最初使用
cabalbuild
构建它。现在我更改一个只影响一个可执行文件的文件,cabal似乎需要大约一两秒钟的时间来检查每个可执行文件是否受到影响。另一方面,
make
,给定相等数量的可执行文件和源文件,将在几分之一秒内确定需要重新编译的内容。为什么会有如此巨大的差异?有什么原因吗,阴谋集团不能建立自己版本的makefile并从那里开始吗?

免责声明:我对Haskell或
make
内部结构不够熟悉,无法给出技术细节,但一些网络搜索确实提供了一些与我的建议一致的见解(试图通过提供参考来避免引起意见)。另外,我假设您的makefile正在调用
ghc
,就像
cabal
显然会调用的那样

提议:我认为可能有几个关键原因,但主要原因是
make
是用C编写的,而
cabal
是用Haskell编写的。这将与来自
make
的高级依赖性检查相结合(尽管我不知道如何在不查看源代码的情况下证明这一点)。其他支持理由,如网上所示:

  • 阴谋集团试图做的不仅仅是简单的编译,例如,似乎在包装方面采取了一些措施()
  • cabal是用haskell编写的,尽管运行时是用C()编写的
  • 同样,由于不太熟悉
    make
    内部结构,
    make
    可能只是拥有更快的依赖项检查机制,从而更好地跟踪这些更改。我之所以指出这一点,是因为从OP的角度来看,似乎存在着足够大的差异,阴谋集团可能会对所有依赖性进行全面检查。我怀疑这将是速度差异的主要原因,如果是真的话
无论如何,这些都是开源的,可以从各自的网站(haskell.org/cabal/和savannah.gnu.org/projects/make/)下载,任何人都可以查看实现的细节

根据传递给正在使用的编译器的开关,还可能会看到速度上的许多差异


至少要给你指出正确的方向。

此外,请参见SO线程;显然,make对时间戳做了一个简单的检查,以判断是否发生了变化。阴谋集团似乎只是因为其运作的性质而寻找变化。我对
Cabal
s或
make
s的内部结构也不太了解,但我相当有信心,性能差异与前者是用Haskell编写的关系不大。编译后的Haskell实际上只比C慢一点,前提是您远离某些性能陷阱(严重融合的列表、太多的懒散等)。事实上,有时候一个惯用的Haskell实现会比一个不是特别优化的C解决方案更快!你可以编辑你的答案以加入新的信息或删除发现不正确的东西(例如,有一个相当明显的错误说法,即阴谋集团的速度较慢,因为它是用Haskell而不是C写的)。@dfeuer:leftaroundabout指出,判断一个人是否更快并不总是那么简单(使用“little”等词)和“有时”来表示这一点)。特别是将优化引入到组合中(也提出了一个问题:“
的分布式/发布版本是否真的会使
未优化?”),我们需要根据经验确定哪个更快,为什么更快。查看源代码和编译器优化级别当然是其中的一部分。请注意,虽然
make
始终会重新编译依赖于某个文件的任何内容,但是
cabal build
例如,如果您只更改文件中的一个函数,则不一定会重新编译下游模块。它以某种方式发现接口没有受到影响,并且足以重新链接文件(这通常比重新编译任何文件都要快得多)。顺便说一句,我认为我们应该谈论的其实是ghc-make;cabal只调用它来检查包内的依赖关系。