2013-09-27 83 views
1

我想動態地構建一個長字符串,然後將其寫入文件。 我有類似代碼:構建字符串的有效方法

let str = ref "" 

let appnd s = 
     str := (!str^(Printf.sprintf "%s\n" s)) 

但在運行時,它的工作原理很慢。我認爲這種方法效率不高。建立長串的最佳方式是什麼?

建立字符串,然後寫入文件更好或直接附加字符串到文件?

回答

3

當你附加到一個字符串時,你必須複製它。如果你想象追加n個部分,你最終會製作n * n個副本。如果n很大,這很慢。

您還選擇了一種緩慢的追加方式。它會更快地說:

let append s = str := !str^s^"\n" 

它可能會更好地使用緩衝區而不是字符串。如果你對字符串的最終大小有了一個概念,你可以預先分配一個合適大小的緩衝區。它也更好地包裝了可變狀態。

更新

下面是使用緩衝區一些簡單的代碼:

let buf = Buffer.create 1024 

let append s = 
    Buffer.add_string buf s; 
    Buffer.add_char buf '\n' 

let getstring() = 
    Buffer.contents buf 

這裏有一個會話:

$ ocaml 
     OCaml version 4.00.1 

# #use "b.ml";; 
val buf : Buffer.t = <abstr> 
val append : string -> unit = <fun> 
val getstring : unit -> string = <fun> 
# append "abc";; 
- : unit =() 
# append "def";; 
- : unit =() 
# getstring();; 
- : string = "abc\ndef\n" 

對於它的價值我想嘗試比這更多的功能寫。即,我會將緩衝區傳遞給想要使用它的函數,而不是使其成爲全局變量。

+0

感謝您提供Buffer。在哪裏我可以找到使用緩衝區的例子? –

+0

最後一次檢查時,編譯器爲'!str^s ^「\ n」'做了一些比較愚蠢的事情。在任意數量的字符串連鎖的情況下,我的賭注是在'Printf.sprintf'%s%s%s ...''。 –

+0

這非常出乎意料。謝謝(你的)信息。 (OP的註釋:我添加了示例緩衝區代碼。) –

1

您可以使用Buffer模塊的String.concat函數或數據結構。

關於最後一個問題,我不確定。我認爲這取決於。

+0

謝謝建議Buffer。在哪裏我可以找到使用緩衝區的例子? –

相關問題