This blog has moved on http://blog.khigia.net/blog.html and this post is at http://blog.khigia.net/wp-import/fsharp/2008/03/30/ocaml-vs-f-for-big-integer-surprising-performance-test.html
Was inspired by Rober Pickering post about a post about Euler problem 14 …
Without changing the algorithm, I ran a simple test to compare F#, ocaml byte code and ocaml native code … and the result is quite surprising, for me at least!
The program do a lot of computation on integer (even 64 bits); I remember (no ref) that ocaml is more efficient for floating point operation that for integer. But anyway, just wanted an idea of how to port this code to Ocaml.
Following is the code in F# as seen on cited post:
#light
let rec seq_length x n =
match x with
| x when x = 0L -> (n + 1)
| x when x = 1L -> seq_length 0L (n + 1)
| x when x%2L=0L ->seq_length (x/2L) (n + 1)
| _ -> seq_length (3L*x + 1L) (n + 1)
let rec loop i imax n =
let n’ = seq_length i 0
let imax, n = if n’ > n then i, n’ else imax, n
if i < 1000000L then loop (i + 1L) imax n else imax
print_any (loop 1L 0L 0)[/sourcecode]
And here is an Ocaml version:
[sourcecode language="csharp"]
let ( ** ) = Int64.mul
let ( // ) = Int64.div
let ( %% ) = Int64.rem
let rec seq_length x n =
match x with
| 0L -> (n + 1)
| 1L -> seq_length 0L (n + 1)
| x when x %% 2L = 0L -> seq_length (x // 2L) (n + 1)
| _ -> seq_length (Int64.succ (3L ** x)) (n + 1)
let rec loop i imax n =
let n’ = seq_length i 0 in
let imax, n = if n’ > n then (i, n’) else (imax, n) in
if i < 1000000L then loop (Int64.succ i) imax n else imax
let _ = print_string (Int64.to_string (loop 1L 0L 0))[/sourcecode]
Surprisingly (for me!), the compiled F# code is much faster:
- time mono eul14.exe: 12.979s
- time ./eul14.byte: 58.145s
- time ./eul14.native: 30.234s
I’m not sure why Ocaml seems to be slower for this test. Can it be a GC issue?
March 31, 2008 at 12:11 pm
One reason may be your use of Int64 – which is a boxed value in OCaml. If you compile this on a 64bit box and use the native int type (63 bits for a variety of speed related reasons) it should be much faster. Int64 is used to get “true” 64 bit values and can be used on 32 bit platforms.
April 2, 2008 at 8:57 pm
Hello,
What is the hardware and operating system on which you have run all these examples? Also, do you think you can try to the prepare the syntax without the #light directive? Good day.
Yemi Bedu
April 3, 2008 at 12:39 am
As usual answer from Dr Jon D Harrop, the one he wrote at this subject is very good:
http://caml.inria.fr/pub/ml-archives/caml-list/2008/04/f1d0cb380fa0ab86e9b306537d898a9b.en.html
I thought it wasn’t relevant to say which hardware I used, but indeed I have to say at least that it is a 32-bit machine (running Ubuntu 7.10, mono 1.2.4, F# 1.9.2.9).
@Yemi Bedu: To remove the #light declaration, I just need to fix the “let … in” construct line 10 and 11; however the syntax should not change anything to the produced binary, or am I wrong to think so?
April 27, 2013 at 8:50 pm
I used to be recommended this web site by my cousin.
I’m not certain whether this post is written through him as no one else understand such special approximately my difficulty. You’re wonderful!
Thanks!
May 14, 2013 at 1:18 pm
Everyone loves it when people come together and share thoughts.
Great blog, keep it up!
July 17, 2013 at 9:50 am
I am regular reader, how are you everybody? This post posted
at this website is genuinely fastidious.
December 17, 2015 at 1:54 pm
[…] https://khigia.wordpress.com/2008/03/30/ocaml-vs-f-for-big-integer-surprising-performance-test/ […]