这是我要实现的
功能方式
let sum l = List.fold_left (fun s x -> s+x) 0 l
Run Code Online (Sandbox Code Playgroud)
势在必行
let sum l =
let sum = ref 0 in
List.iter (fun x -> sum := !sum +x) l;
!sum
Run Code Online (Sandbox Code Playgroud)
还有更好/更快的方法吗?
我问这个是因为Real World OCaml这本书说:
# let sum list =
let sum = ref 0 in
List.iter list ~f:(fun x -> sum := !sum + x);
!sum
;;
val sum : int list -> int = <fun>
Run Code Online (Sandbox Code Playgroud)
This isn't the most idiomatic (or the fastest) way to sum up a list, but it shows how you can use a ref in place of a mutable variable.
sea*_*mcl 10
这稍微凉爽;)
let sum l = List.fold_left (+) 0 l;;
Run Code Online (Sandbox Code Playgroud)
要看性能:
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"
;;
Run Code Online (Sandbox Code Playgroud)
给予
$ 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
Run Code Online (Sandbox Code Playgroud)
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!
Run Code Online (Sandbox Code Playgroud)
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!
Run Code Online (Sandbox Code Playgroud)
谁知道为什么?
| 归档时间: |
|
| 查看次数: |
204 次 |
| 最近记录: |