簡體   English   中英

在內存中保存大型可編輯文檔的最佳方法

[英]Best approach to holding large editable documents in memory

我需要在內存中保存文檔的表示,並且正在尋找最有效的方法來執行此操作。

假設

  • 文檔可能非常大,高達100MB。
  • 通常情況下,文檔將保持不變 - (即我不想進行不必要的預先處理)。
  • 更改通常在文檔中彼此非常接近(即,作為用戶類型)。
  • 應該可以快速應用更改(不復制整個文檔)
  • 更改將應用​​於偏移和新/刪除的文本(而不是行/列)。
  • 在C#中工作

目前的考慮

  • 將數據存儲為字符串。 易於編碼,設置快速,更新速度非常慢。
  • 行數組,模式易於編碼,設置較慢(因為我們必須將字符串解析為行),更新速度更快(因為我們可以輕松插入刪除行,但查找偏移量需要求和行長度)。

對於這種事情,必須有大量標准算法(這不是一百萬英里的磁盤分配和碎片)。

謝謝你的想法。

我建議將文件分成塊。 加載時,所有塊都具有相同的長度,但如果用戶編輯此塊,則每個塊的長度可能會更改。 如果用戶在前面插入一個字節,這可以避免移動100兆字節的數據。

要管理塊,只需將它們與每個塊的偏移量一起放入列表中。 如果用戶修改了塊長度,則必須僅在此塊之后更新塊的偏移量。 要查找偏移量,可以使用二分查找。

文件大小: 100 MiB
塊大小: 16 kiB
街區:6400

使用二分查找(最差情況)查找偏移量: 13個步驟
修改塊(最壞情況):復制16384字節數據並更新6400塊偏移
修改塊(平均情況):復制8192字節數據並更新3200塊偏移

16 kiB塊大小只是一個隨機示例 - 您可以通過選擇塊大小來平衡操作的成本,可能基於文件大小和操作概率。 做一些簡單的數學運算將產生最佳的塊大小。

加載速度非常快,因為你加載固定大小的塊,並且保存也應該運行良好,因為你必須編寫幾千個塊而不是數百萬個單行。 您可以通過僅按需加載塊來優化加載,並且您可以通過僅保存更改的所有塊(內容或偏移)來優化保存。

最后,實施也不會很難。 您可以使用StringBuilder類來表示塊。 但是這種解決方案不適用於長度與塊大小相當或更大的非常長的線路,因為您將需要加載許多塊並僅顯示一小部分,其余部分位於窗口的左側或右側。 我假設在這種情況下你將不得不使用二維分區模型。

Good Math,Bad Math寫了一篇關於繩索和間隙緩沖區 sa的優秀文章 ,詳細介紹了在文本編輯器中表示文本文件的標准方法,甚至比較它們以簡化實現和性能。 簡而言之:間隙緩沖區 - 一個大字符數組,在光標的當前位置之后立即有一個空部分 - 是最簡單和最好的選擇。

您可能會發現本文很有用--- 文本序列的數據結構,它描述並實驗分析了一些標准算法,並比較[等等]間隙緩沖區和片段表。

FWIW,總結表格總體上略勝一籌; 雖然net.wisdom似乎更喜歡間隙緩沖區。

如果您不打算編輯太多,我會使用b樹或跳過行列表或更大的塊。

由於您無論如何都必須在加載時訪問每個字符,因此加載時沒有太多額外成本確定行結束。

您可以毫不費力地在節點內移動線條。

每個節點中文本的總長度存儲在節點中,並且更改傳播到父節點。

每行由數據數組表示,並且起始索引,長度和容量。 換行符/回車符不放在數據數組中。 諸如斷行之類的常見操作僅需要更改對數組的引用; 如果超出容量,編輯行需要副本。 編輯該行時,每行可能會臨時使用類似的結構,因此您不會在每次按鍵時執行復制。

除了你有一些非常長的行之外,我認為索引鏈表對於這類事情是相當有效的。

鏈接列表將為您提供一種有效的方式來存儲數據,並在用戶編輯時添加或刪除行。 索引允許您快速跳轉到文件中的特定點。 這種想法很適合撤消/重做類型操作,因為將編輯分類為小型原子操作應該相當容易。

我同意crisb的觀點,但最好先讓一些簡單的工作,然后看看它是否真的慢......

從你的描述中聽起來很像你的文檔只是未格式化的文本 - 所以一個字符串構建器就可以了。

如果它是一個格式化的文檔,我傾向於使用MS Word API或類似的東西,只是將文檔處理卸載到它們 - 將節省您大量的時間,因為文檔解析通常是一個痛苦的**: - )

我不會太擔心性能 - 聽起來很像你還沒有實現它,所以你也不知道應用程序其余部分的性能特征 - 可能是你不能實際上,當你實際進行分析時,實際上可以在內存中保存多個文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM