我是OCaml的新手(在Haskell有一些先验知识)。我想说服自己采用OCaml。因此,我试图比较C和OCaml之间的性能。我编写了以下天真的Monte -finder:
C版
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
const int N = 10000000;
const int M = 10000000;
int count = 0;
for (int i = 0; i < N; i++) {
double x = (double)(random() % (2 * M + 1) - M) / (double)(M);
double y = (double)(random() % (2 * M + 1) - M) / (double)(M);
if (x * x + y * y <= 1) {
count++;
}
}
double pi_approx = 4.0 * (double)(count) / (double)(N);
printf("pi .= %f", pi_approx);
return 0;
}Ocaml版本
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我用Clang编译了C(AppleLLVMVersion5.1),用ocamlopv4.01.0编译了OCaml。
C的运行时间为0.105 s。OCaml的速度是0.945s,是原来的9倍。我的目标是将OCaml的运行时间减少3倍,使程序能够在0.315s内完成。
由于我对OCaml非常陌生,所以我想学习一些OCaml优化技术。请给我一些建议!(已经应用了尾递归,否则程序会因堆栈溢出而崩溃)
发布于 2014-06-28 05:56:40
如果在两个测试中使用相同的随机数生成器,我会看到以下情况。
下面是从OCaml调用随机()的存根:
#include <stdlib.h>
#include <caml/mlvalues.h>
value crandom(value v)
{
return Val_int(random());
}下面是修改后的OCaml代码:
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我也没有修改你的C代码。
下面是在我的Mac (2.3 GHz Intel Core i7)上展示这两个程序的会话:
$ 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看起来OCaml代码慢了15%左右。
我根本没有试图让它更快,我只是用C代码正在使用的一个随机数生成器来代替它。
实际上,您的代码似乎很难改进(也就是说,它是好代码)。
编辑
(我重写了存根以使其更快。)
https://stackoverflow.com/questions/24463701
复制相似问题