Compilation OCaml编译速度&;仿函数 使用OcAML中的函子在编译时基本上是运行代码(这样我认为它们更接近C++模板,然后更接近java泛型)。

Compilation OCaml编译速度&;仿函数 使用OcAML中的函子在编译时基本上是运行代码(这样我认为它们更接近C++模板,然后更接近java泛型)。,compilation,ocaml,functor,Compilation,Ocaml,Functor,因此,我的问题是:编译器是否在编译之前执行任何优化,或者它是否立即开始生成代码,或者它是否尝试在编译之前执行任何优化 这个问题看起来更实际。我经常使用Map.Make或类似的函子为给定类型生成Map/hashtable/etc。当我在多个模块中使用它时,我开始担心,因为我认为编译器将开始多次执行相同的操作(编译速度开始成为我的一个问题,尤其是在脚本语言背景下)。 那么我需要担心吗?或者,如果我在多个模块中执行Map.Make(MyModule),编译器会不会说“ohai,我刚刚用这种类型编译了这

因此,我的问题是:编译器是否在编译之前执行任何优化,或者它是否立即开始生成代码,或者它是否尝试在编译之前执行任何优化

这个问题看起来更实际。我经常使用
Map.Make
或类似的函子为给定类型生成Map/hashtable/etc。当我在多个模块中使用它时,我开始担心,因为我认为编译器将开始多次执行相同的操作(编译速度开始成为我的一个问题,尤其是在脚本语言背景下)。 那么我需要担心吗?或者,如果我在多个模块中执行
Map.Make(MyModule)
,编译器会不会说“ohai,我刚刚用这种类型编译了这个函子,我可能不需要再这样做了?”

是的,我知道我可以有一个单独的utils模块并运行其中的所有函子,但我通常会尽量避免使用utils,比如厨房水槽模块

编译器会不会说“ohai,我刚刚用这种类型编译了这个函子,我可能不需要再这样做了?”

<>你正在考虑模板通常由C++编译器编译的方式。而
ocamlc
ocamlopt
的编译方案会生成不需要复制的通用代码


OCaml functor
Map.Make
对于它可能应用到的所有模块只编译一次。从
Map.Make(String)
调用
iter
和从
Map.Make(Float)
调用
iter
时,执行相同的代码。或者当你从两个不同的
Map.Make
String

应用程序运行
iter
时,看起来我完全误解了模块系统。。。但是我很困惑。OCaml中的浮点和整数在OCaml中没有装箱,对吗?同一代码如何可能在两种不同的未绑定类型上运行?实际上,使用类型擦除的盒式类型怎么可能呢?@cheshire OCaml float是盒式的。只有浮点数组包含未绑定的浮点。OCaml int的大小与指针相同,并且设置了最低有效位以区别于指针。因此,两种不同的
int
大小使得OCaml代码的可移植性不如Java代码,而且这两种大小分别为31位和63位。谢谢!那我就回去读书了。。。出于某种原因,我认为OCaml的优点在于它在编译时知道哪些函数确切地使用了哪种类型,因此可以为非固定值生成非常快的代码。我还对OCaml如何击败Java性能感到困惑(一般而言)因为在Java中,从
float
切换到
float
会导致性能大幅下降,而OCaml总是使用一个装箱值。@cheshire Java中有很多与性能相反的地方。但是,作为一个喜欢阅读OCaml生成的汇编代码的人(如果您想亲自查看泛型代码,我建议您使用这种方法),OCaml也有很多不必要的浮动装箱/取消装箱操作,编译器实现者只是开始消除最明显的浮动。在任何情况下,请注意,OCaml浮动被装箱都是有原因的,而且Java通过在堆栈上放置未装箱的浮动而获得的好处是,它必须使用更复杂或更保守的垃圾回收器,这可能会在总体性能上损失更多。