2009-11-11 105 views
7

有些功能是很容易在OCaml中实现(例如,从列表地图),但你可以使用OCaml的库图:List.mapOCaml的模块和性能

但是,我们可以知道哪些代码会更有效率。调用单独编译单元(库)的模块可能会使一些可能的优化失效。我在新闻组fa.caml中读到,当从库中调用函数时,会使用闭包。

我在生产中使用模块和函数进行泛型编程的OCaml代码。由于历史原因,我的代码是monolitic:全部在一个文件中。现在我有更多的时间,我愿意将代码分离成这些模块的文件。但是,恐怕我会失去表现,因为我花了一段时间才弄清楚了。例如,我有用于用数字包装复杂对象的模块,因此我执行了独特的表示和快速比较。我将这些包装的对象与通用的地图,集合一起使用,并在其上构建缓存。

的问题是:

  • 我要去松动的表现,如果我移动到单独的文件?
  • OCaml是否对我的模块,仿函数等代码做了很多优化?

在C++中,如果您在.h中定义类方法,编译器可能会结束内联短方法等。是否可以使用分隔文件在OCaml中实现该方法?

+0

我不太了解ocaml编译器和链接器的内部,所以我无法回答你的问题。但是,如果您将代码分解为模块而失去了性能,那么我会非常惊讶。即使你确实损失了几毫秒,代码的清晰度也会提高。 – 2009-11-11 19:29:51

+0

在C/C++中可能会导致巨大的差异。我拥有数百万个对象,访问/比较了数十万次。每次访问的一组辅助参考可能非常糟糕。 – hectorpal 2009-11-12 06:56:32

+0

是的,但是编译器应该内联这些引用,以便实际上不需要进行更多的查找。你如何试着用一堆虚拟模块做一个测试项目,并试着衡量把它们分解并保存在同一个文件中是否有区别。这可能比重构工作代码库少很多。希望这会给你更多的信心,ocamlopt将能够智能地优化你的代码。 – 2009-11-13 19:42:20

回答

9

您可能会失去一些性能。但是,有两个缓解因素:

  • OCaml的本地代码编译器可以做跨模块内联,所以它是可能的代码,甚至跨越不同的编译单元内联(与一对夫妇告诫 - 递归函数和函数参数不跨模块[1])内联。
  • 代码仍然很可能足够快,可读性和可维护性的提高很可能会超过任何(边际)性能成本。

我不知道OCaml defunctorizes函数在同一个源文件中定义的代码。如果没有,那么模块不应该增加任何已经由仿函数引起的性能。

一般来说,我认为最好是编写简单易读,可维护的代码,而不必太担心这样的微观性能特性,除非代码在实践中证明速度太慢。

+0

谢谢迈克尔。好信息。当然,我知道我会获得可读性。我现在所拥有的并不令人满意。但是,在我的情况下,运行时性能是一个关键问题。我已经投入了很多时间从列表切换到数组(我正在使用Res库来增加数组)。我也有大量的缓存并仔细选择数据结构。我认为我做了我所做的事情,从10分钟或10分钟降至10秒。我现在关心的主要是关于用数百万个对象来表示的模块。无论如何,我会分裂,但我需要表明这种影响,并且不得分裂所有。 – hectorpal 2009-11-12 06:52:04

+0

一旦完成重构代码,根据需要选择性地将某些模块移回主文件应该相对容易。 – 2009-11-18 09:18:22