Performance OCaml优化技术
我是OCaml新手(之前对Haskell有一些了解)。我想说服自己采用OCaml。因此,我尝试比较C和OCaml之间的性能。我写了以下天真的Monte Carlo Pi finder: C版本Performance OCaml优化技术,performance,optimization,functional-programming,ocaml,Performance,Optimization,Functional Programming,Ocaml,我是OCaml新手(之前对Haskell有一些了解)。我想说服自己采用OCaml。因此,我尝试比较C和OCaml之间的性能。我写了以下天真的Monte Carlo Pi finder: C版本 #包括 #包括 int main(int argc,const char*argv[]{ 常数整数N=10000000; 常数int M=10000000; 整数计数=0; 对于(int i=0;i 设x=float_of_int(Random.int(2*m+1)-m)/(float_of_int m)
#包括
#包括
int main(int argc,const char*argv[]{
常数整数N=10000000;
常数int M=10000000;
整数计数=0;
对于(int i=0;i
设x=float_of_int(Random.int(2*m+1)-m)/(float_of_int m)in
设y=float_of_int(Random.int(2*m+1)-m)/(float_of_int m)in
如果x*.x+.y*.y这是我在两个测试中使用相同的随机数生成器时看到的结果
下面是从OCaml调用random()的存根:
#include <stdlib.h>
#include <caml/mlvalues.h>
value crandom(value v)
{
return Val_int(random());
}
看起来OCaml代码要慢15%左右
我根本没有试图让它更快,我只是用C代码正在使用的随机数生成器替换了随机数生成器
实际上,您的代码似乎很难改进(即,它是一个好代码)
编辑
(我重写了存根以加快速度。)一条评论是,这很可能主要是对两个随机数生成器进行计时。它们的速度在语言和实现之间存在巨大差异。您可以尝试在两个测试中使用相同的生成器。
let findPi m n =
let rec countPi count = function
| 0 -> count
| n ->
let x = float_of_int (Random.int (2 * m + 1) - m) /. (float_of_int m) in
let y = float_of_int (Random.int (2 * m + 1) - m) /. (float_of_int m) in
if x *. x +. y *. y <= 1. then
countPi (count + 1) (n - 1)
else
countPi count (n - 1) in
4.0 *. (float_of_int (countPi 0 n)) /. (float_of_int n);;
let n = 10000000 in
let m = 10000000 in
let pi_approx = findPi m n in
Printf.printf "pi .= %f" pi_approx
#include <stdlib.h>
#include <caml/mlvalues.h>
value crandom(value v)
{
return Val_int(random());
}
external crandom : unit -> int = "crandom"
let findPi m n =
let rec countPi count = function
| 0 -> count
| n ->
let x = float_of_int (crandom () mod (2 * m + 1) - m) /. (float_of_int m) in
let y = float_of_int (crandom () mod (2 * m + 1) - m) /. (float_of_int m) in
if x *. x +. y *. y <= 1. then
countPi (count + 1) (n - 1)
else
countPi count (n - 1) in
4.0 *. (float_of_int (countPi 0 n)) /. (float_of_int n);;
let n = 10000000 in
let m = 10000000 in
let pi_approx = findPi m n in
Printf.printf "pi .= %f" pi_approx
$ time findpic
pi .= 3.140129
real 0m0.346s
user 0m0.343s
sys 0m0.002s
$ time findpic
pi .= 3.140129
real 0m0.342s
user 0m0.340s
sys 0m0.001s
$ time findpiml
pi .= 3.140129
real 0m0.396s
user 0m0.394s
sys 0m0.002s
$ time findpiml
pi .= 3.140129
real 0m0.395s
user 0m0.393s
sys 0m0.002s