views:

473

answers:

1

Some functions are really easy to implement in OCaml (for example, map from a list) but you may use the map of the OCaml library: List.map

However, we can wonder which code will be more efficient. Calling a module of a separate compilation unit (a library) may void some possible optimizations. I read in the news group fa.caml that when calling functions from libraries, closures are used.

I have OCaml code in production that use Modules and Functors for doing generic programming. For historical reason my code is monolitic: all in one file. Now I have more time, I'm willing to separate the code into files for such modules. However, I'm afraid I can lost performance, as it took me a while to get it right. For example, I have modules for wrapping complex objects with numbers, so I enforce unique representation and fast comparison. I use those wrapped objects with generic Maps, Sets, and build caches upon them.

The questions are:

  • Am I going to loose performance if I move to separate files?
  • Is OCaml doing many optimizations on my code full of modules, functors, etc?

In C++, if you define class method in a .h, the compiler may end up inlining short methods, etc. Is it possible to achieve that in OCaml using separated files?

+4  A: 

You may lose some performance. However, there are two mitigating factors:

  • The OCaml native code compiler can do cross-module inlining, so it is possible for code to be inlined even across the separate compilation units (with a couple caveats - recursive functions and function arguments are not inlined across modules[1]).
  • The code will still quite possibly be fast enough, and the gains in readability and maintainability will quite possibly outweigh any (marginal) performance cost.

I do not know if OCaml defunctorizes code where the functors are defined in the same source file. If it does not, then modules shouldn't add any performance hit above that already incurred by the functors.

In general, it is my opinion that it is best to write straightforward, readable, maintainable code and not worry too much about microscopic performance characteristics like this unless the code proves to be too slow in practice.

Michael E
Thanks Michael. Good info. Of course I know I will gain readability. What I have now is not satisfactory. However, in my case runtime performance is a critical issue. I have already invested a lot of time on switching from list to array (I'm using now the Res library for growing arrays). I also have tons of cache and carefully choosen datastructure. I think I went down from 10 minuts or worst to 10 seconds by doing what I did. My concern is now mainly about modules that wrap representation of millions of objects. I will split anyway, but I need to assest the impact and may not split all.
hectorpal
once you're done refactoring code, it should be relatively easy to selectively move some modules back into the main file as needed.
Martin DeMello