これは少し涼しいです;)
let sum l = List.fold_left (+) 0 l;;
パフォーマンスを確認するには:
open Printf
let sum1 l = List.fold_left (fun s x -> s+x) 0 l;;
let sum2 l = List.fold_left (+) 0 l;;
let sum3 = List.fold_left (+) 0;;
let rec make_list x acc = function
| 0 -> acc
| n -> make_list x (x :: acc) (n-1)
let l = make_list 1 [] 50000000;;
let _ = match Sys.argv.(1) with
| "1" -> printf "%d\n" (sum1 l)
| "2" -> printf "%d\n" (sum2 l)
| "3" -> printf "%d\n" (sum3 l)
| _ -> printf "Bad arg\n"
;;
与える
$ ocamlc foo.ml
$ time ./a.out 1
50000000
real 0m8.204s
user 0m7.211s
sys 0m0.848s
$ time ./a.out 2
time ./a.out 3
50000000
real 0m8.226s
user 0m7.325s
sys 0m0.818s
$ 50000000
real 0m8.472s
user 0m7.561s
sys 0m0.837s
sum1 と sum2 のバイトコードはまったく同じです。
branch L2
restart
L3: grab 1
acc 1
push
acc 1
addint
return 2
L1: acc 0
push
const 0
push
closure L3, 0
push
getglobal List!
getfield 14
appterm 3, 4
L2: closure L1, 0
push
acc 0
makeblock 1, 0
pop 1
setglobal Foo1!
sum3 のバイトコードは小さいが遅い
branch L2
restart
L1: grab 1
acc 1
push
acc 1
addint
return 2
L2: const 0
push
closure L1, 0
push
getglobal List!
getfield 14
apply 2
push
acc 0
makeblock 1, 0
pop 1
setglobal Foo3!
理由を知っている人はいますか?