File Ocaml相当慢的文件读取器
我有下面的代码来读取一个文件,它删除了文件中的每个注释File Ocaml相当慢的文件读取器,file,ocaml,File,Ocaml,我有下面的代码来读取一个文件,它删除了文件中的每个注释 let s_read_all line = if line = "" then raise Pbm_format_error else if line.[0] = '#' then "" else line ^ "\n" ;; let read_all flec = let rec loop accum_ref = let line = i
let s_read_all line =
if line = "" then
raise Pbm_format_error
else if line.[0] = '#' then
""
else
line ^ "\n"
;;
let read_all flec =
let rec loop accum_ref =
let line = input_line flec in
accum_ref := (!accum_ref) ^ (s_read_all line);
loop accum_ref
in
let accum_ref = ref "" in
try
loop accum_ref
with
End_of_file -> !accum_ref
;;
我的代码对于180k行来说非常慢(大约2分钟)。我在解释器模式下执行它。这就是为什么我的代码这么慢的原因吗?问题是字符串连接很慢。更准确地说,它的重复字符串连接速度很慢。应使用缓冲区而不是字符串来累加行:
let read_all flec =
let rec loop buffer =
let line = input_line flec in
Buffer.add_string buffer (s_read_all line);
loop buffer
in
let buffer = Buffer.create 180 in
try
loop buffer
with
End_of_file -> Buffer.content buffer
;;
问题是字符串连接很慢。更准确地说,它的重复字符串连接速度很慢。应使用缓冲区而不是字符串来累加行:
let read_all flec =
let rec loop buffer =
let line = input_line flec in
Buffer.add_string buffer (s_read_all line);
loop buffer
in
let buffer = Buffer.create 180 in
try
loop buffer
with
End_of_file -> Buffer.content buffer
;;
您正在使用
行^“\n”
和(!accum\u ref)^(s\u read\u all行)代码>
与Java中一样,^
是直接concat,将不断创建新字符串。所以我想这就是为什么180K线速度慢的原因
您应该使用,就像Java中的StringBuilder一样
另外,如果您为Buffer.create
指定了一个合适的初始长度,则会稍微快一点
exception Pbm_format_error
let s_read_all line =
if line = "" then
raise Pbm_format_error
else if line.[0] = '#' then
""
else
line
let read_all flec =
let rec loop accum_buf =
let line = s_read_all (input_line flec) in
Buffer.add_string accum_buf line;
if line <> "" then Buffer.add_string accum_buf "\n" else ();
loop accum_buf
in
let accum_buf = Buffer.create (180 * 1000 * 128) in
try
loop accum_buf
with
End_of_file -> Buffer.contents accum_buf
异常Pbm\u格式\u错误
让我们通读这一行=
如果line=”“,则
引发Pbm_格式_错误
否则,如果行[0]=“#”,则
""
其他的
线
让我们读一读所有的flec=
让rec循环累计buf=
让line=s\u读取所有(输入行flec)输入
Buffer.add_字符串累计行;
如果是行“”,则Buffer.add_string accum_buf“\n”else();
循环累计
在里面
让accum_buf=Buffer.create(180*1000*128)在
尝试
循环累计
具有
结束\u文件->Buffer.contents累计\u buf
您正在使用行^“\n”
和(!accum\u ref)^(s\u read\u all line)代码>
与Java中一样,^
是直接concat,将不断创建新字符串。所以我想这就是为什么180K线速度慢的原因
您应该使用,就像Java中的StringBuilder一样
另外,如果您为Buffer.create
指定了一个合适的初始长度,则会稍微快一点
exception Pbm_format_error
let s_read_all line =
if line = "" then
raise Pbm_format_error
else if line.[0] = '#' then
""
else
line
let read_all flec =
let rec loop accum_buf =
let line = s_read_all (input_line flec) in
Buffer.add_string accum_buf line;
if line <> "" then Buffer.add_string accum_buf "\n" else ();
loop accum_buf
in
let accum_buf = Buffer.create (180 * 1000 * 128) in
try
loop accum_buf
with
End_of_file -> Buffer.contents accum_buf
异常Pbm\u格式\u错误
让我们通读这一行=
如果line=”“,则
引发Pbm_格式_错误
否则,如果行[0]=“#”,则
""
其他的
线
让我们读一读所有的flec=
让rec循环累计buf=
让line=s\u读取所有(输入行flec)输入
Buffer.add_字符串累计行;
如果是行“”,则Buffer.add_string accum_buf“\n”else();
循环累计
在里面
让accum_buf=Buffer.create(180*1000*128)在
尝试
循环累计
具有
结束\u文件->Buffer.contents累计\u buf