(* いつもの *)
let rec map1 f = function
  [] -> []
 | x :: xs -> (f x) :: (map1 f xs)
;;

(* CPS 変換 *)
let map2 f lst =
 let rec map2_sub k f = function
   [] -> k []
  | x :: xs ->
   let t = f x in
   map2_sub (fun y -> t :: y) f xs
 in
 map2_sub (fun x -> x) f lst
;;

(* adhoc tail-call *)
let map3 f lst =
 let rec map3_sub f result = function
   [] -> result
  | x :: xs -> map3_sub f ((f x) :: result) xs
 in
 map3_sub f [] (List.rev lst)
;;

どれが早いでしょう。