String.concat
Florent Monnier <[email protected]> Thu, 6 May 2010 00:30:21 +0200
| Newsgroups | gmane.comp.lang.ocaml.lib.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi,
It's possible to enhance String.concat a little bit.
(Find the patch joined to this email.)
Indeed in the std-lib there are extraneous calls to String.length.
Here is a short bench that shows the difference:
let _concat sep l =
let len_sep = String.length sep in
match l with
[] -> ""
| hd :: tl ->
let len_hd = String.length hd in
let num = ref 0 and len = ref 0 in
List.iter (fun s -> incr num; len := !len + String.length s) l;
let r = String.create (!len + len_sep * (!num - 1)) in
String.unsafe_blit hd 0 r 0 len_hd;
let pos = ref len_hd in
List.iter
(fun s ->
let len_s = String.length s in
String.unsafe_blit sep 0 r !pos len_sep;
pos := !pos + len_sep;
String.unsafe_blit s 0 r !pos len_s;
pos := !pos + len_s)
tl;
r
let time_it lbl n f v =
let t1 = Unix.gettimeofday() in
for i = 1 to n do
let _ = f v in ()
done;
let t2 = Unix.gettimeofday() in
Printf.printf " %s %f sec.\n" lbl (t2 -. t1);
;;
let () =
let li = ["The"; "quick"; "brown"; "fox"; "jumps"; "over"; "the"; "lazy";
"dog"] in
let n = 1_000_000 in
time_it "std :" n (String.concat " ") li;
time_it "custom:" n (_concat " ") li;
;;
_____________________________
here is an example output:
std : 0.462470 sec.
custom: 0.410706 sec.
================================
In the std-lib concat is written like this:
let concat_ sep l =
match l with
[] -> ""
| hd :: tl ->
let num = ref 0 and len = ref 0 in
List.iter (fun s -> incr num; len := !len + length s) l;
let r = create (!len + length sep * (!num - 1)) in
unsafe_blit hd 0 r 0 (length hd);
let pos = ref(length hd) in
List.iter
(fun s ->
unsafe_blit sep 0 r !pos (length sep);
pos := !pos + length sep;
unsafe_blit s 0 r !pos (length s);
pos := !pos + length s)
tl;
r
================================
--
Regards
------------------------------------------------------------------------------
_______________________________________________
ocaml-lib-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ocaml-lib-devel
extlib-1.5.1-extString.ml.patch
(text/x-patch, 865 B)
--- extlib-1.5.1/extString.ml.orig 2010-05-06 00:17:33.000000000 +0200 +++ extlib-1.5.1/extString.ml 2010-05-06 00:19:10.000000000 +0200 @@ -104,6 +104,27 @@ nsplit str sep ) +let concat sep l = + let len_sep = length sep in + match l with + [] -> "" + | hd :: tl -> + let len_hd = length hd in + let num = ref 0 and len = ref 0 in + List.iter (fun s -> incr num; len := !len + length s) l; + let r = create (!len + len_sep * (!num - 1)) in + unsafe_blit hd 0 r 0 len_hd; + let pos = ref len_hd in + List.iter + (fun s -> + let len_s = length s in + unsafe_blit sep 0 r !pos len_sep; + pos := !pos + len_sep; + unsafe_blit s 0 r !pos len_s; + pos := !pos + len_s) + tl; + r + let join = concat let slice ?(first=0) ?(last=Sys.max_string_length) s =