URLエンコード(ocaml)
急にocamlのコードを書いてみたくなったので、以前に他言語用に書いたURLエンコードのソースをocamlに翻訳した。
以下、成果物のメモ。
(* file: url_encode.ml *) (* Read whole file *) (* refer: http://www.ocaml-tutorial.org/ja/if_statements,_loops_and_recursion *) let read_whole_chan chan = let len = in_channel_length chan in let result = String.create len in really_input chan result 0 len; result ;; let read_whole_file filename = let chan = open_in filename in read_whole_chan chan ;; (* URL encode *) let is_safe_char c = match c with '0'..'9' | 'a'..'z' | 'A'..'Z' | '.' | '-' | '_' | '*' -> true | _ -> false ;; let encode_char_to_hex c buf = String.set buf 1 "0123456789ABCDEF".[(int_of_char c land 0xF0) lsr 4]; String.set buf 2 "0123456789ABCDEF".[int_of_char c land 0x0F]; buf ;; let url_encode s = let hexbuf = "%__" in let dist = Buffer.create 1024 in let conv c = if is_safe_char c then Buffer.add_char dist c else if c=' ' then Buffer.add_char dist '+' else Buffer.add_string dist (encode_char_to_hex c hexbuf) in String.iter conv s; Buffer.contents dist ;; (* main *) let s = read_whole_file Sys.argv.(1) in url_encode s;;
コンパイルと計時。
# 処理速度を重視するコンパイラオプションとかはあるのか? $ ocamlopt url_encode.ml -o url_encode # 夏目漱石の『こころ』(UTF-8,542KB)をエンコード $ time url_encode /path/to/kokoro real 0m0.053s user 0m0.052s sys 0m0.000s
速度的に悪くはないけど、他の言語で作成したものよりは遅い(C++: 0.025s, sbcl: 0.032s)。
多分(上のコードよりも)もっと効率的に文字列を操作する方法があるんだろうな。