From: Richard J. <ri...@an...> - 2004-06-22 16:19:58
|
let replace f s = let len = String.length s in let tlen = ref 0 in let rec loop i acc = if i = len then acc else let s = f (unsafe_get s i) in tlen := !tlen + length s; loop (i-1) (s :: acc) ^^^^^------------------------ should be (i+1) in let strs = loop 0 [] in let sbuf = create !tlen in let pos = ref !tlen in let rec loop2 = function | [] -> () | s :: acc -> let len = length s in pos := !pos - len; blit s 0 sbuf !pos len; loop2 acc in loop2 strs; sbuf -- Richard Jones. http://www.annexia.org/ http://www.j-london.com/ Merjis Ltd. http://www.merjis.com/ - improving website return on investment C2LIB is a library of basic Perl/STL-like types for C. Vectors, hashes, trees, string funcs, pool allocator: http://www.annexia.org/freeware/c2lib/ |
From: Nicolas C. <war...@fr...> - 2004-06-22 16:42:00
|
> let replace f s = > let len = String.length s in > let tlen = ref 0 in > let rec loop i acc = > if i = len then acc else > let s = f (unsafe_get s i) in > tlen := !tlen + length s; > loop (i-1) (s :: acc) > ^^^^^------------------------ should be (i+1) This is now fixed on the CVS, Thanks for the report, Regards, Nicolas Cannasse |
From: skaller <sk...@us...> - 2004-06-22 17:05:44
|
On Wed, 2004-06-23 at 02:19, Richard Jones wrote: why is it so complex? > let replace f s = > let len = String.length s in > let tlen = ref 0 in > let rec loop i acc = > if i = len then acc else > let s = f (unsafe_get s i) in > tlen := !tlen + length s; > loop (i-1) (s :: acc) > ^^^^^------------------------ should be (i+1) This function is simpler, faster and uses less memory.. let replace f s = let n = String.length s in let b = Buffer.create (n+20) in (* this can be improved *) for i = 0 to n - 1 do Buffer.add_string b (f (unsafe_get s i)) done; Buffer.contents b This function can be improved by improving the estimate on the output length or tuning the Buffer growth formula. [Extlib's Buffer can do that right?] So one might add an optional labelled tuning argument or several, for computing an estimate (use the same ones as ExtBuffer?) -- John Skaller, mailto:sk...@us... voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net |
From: Richard J. <ri...@an...> - 2004-06-23 11:25:38
|
I also wonder if String.replace wouldn't be simpler and faster if the f function was defined as: f : char -> string option If f returns None, then the original char should be inserted into the string. This avoids the common case where f calls 'String.make 1 c' and so builds lots of length-1 strings. Example: let javascript_quote str = "'" ^ replace (function | '\'' -> "\\'" | '\\' -> "\\\\" | '\n' -> "\\n" | '\r' -> "" | c -> String.make 1 c) str ^ "'" changed to: let javascript_quote str = "'" ^ replace (function | '\'' -> Some "\\'" | '\\' -> Some "\\\\" | '\n' -> Some "\\n" | '\r' -> Some "" | _ -> None) str ^ "'" Rich. -- Richard Jones. http://www.annexia.org/ http://www.j-london.com/ Merjis Ltd. http://www.merjis.com/ - improving website return on investment MONOLITH is an advanced framework for writing web applications in C, easier than using Perl & Java, much faster and smaller, reusable widget-based arch, database-backed, discussion, chat, calendaring: http://www.annexia.org/freeware/monolith/ |
From: skaller <sk...@us...> - 2004-06-23 14:56:30
|
On Wed, 2004-06-23 at 21:25, Richard Jones wrote: > I also wonder if String.replace wouldn't be simpler and faster if the > f function was defined as: > > f : char -> string option The replace function would be more complex obviously, however the client conversion function would be simpler and the total result faster I think, so I think I'd tend to support Richard's suggestion here. Interesting this wouldn't be so in Python, which has a very efficient string representation (and needs it since there is no concept of a char). -- John Skaller, mailto:sk...@us... voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net |