读取OCaml中的所有字符太慢了

时间:2014-10-01 15:17:11

标签: ocaml ocaml-core

我是OCaml的初学者,我想从文件中读取行,然后检查每行中的所有字符。 作为一个虚拟的例子,让我们说我们想要计算角色的出现次数' A'在文件中。

我尝试了以下

open Core.Std

let count_a acc string = 
    let rec count_help res stream =
        match Stream.peek stream with
        | None -> res
        | Some char -> Stream.junk stream; if char = 'A' then count_help (res+1) stream else count_help res stream
    in acc + count_help 0 (Stream.of_string string)

let count_a = In_channel.fold_lines stdin ~init:0 ~f:count_a

let () = print_string ((string_of_int count_a)^"\n"

我用

编译它
 ocamlfind ocamlc -linkpkg -thread -package core -o solution solution.ml

运行它
$./solution < huge_file.txt

在一个有一百万行的文件上,这给了我以下时间

real    0m16.337s
user    0m16.302s
sys 0m0.027s

这是我的python实现的4倍。我相当肯定应该可以让它变得更快,但我该如何去做呢?

1 个答案:

答案 0 :(得分:2)

要计算字符串中的字符数,您只需使用String.count函数即可。实际上,最简单的解决方案是:

open Core.Std

let () =
  In_channel.input_all stdin |>
  String.count ~f:(fun c -> c = 'A') |>
  printf "we have %d A's\n"

更新

稍微复杂一点(并且需要更少内存的解决方案),[fold_lines]将如下所示:

let () =
  In_channel.fold_lines stdin ~init:0 ~f:(fun n s ->
    n + String.count ~f:(fun c -> c = 'A') s) |>
    printf "we have %d A's\n"

实际上,它比前一个慢。在我8岁的笔记本电脑上花了7.3秒,算上A&#39;在20兆字节的文本文件中。前一个解决方案需要3秒钟。

另外,我希望你能发现这个post很有意思。