【问题标题】:Best Way To Pre-process And Search A Text File In .NET CF在 .NET CF 中预处理和搜索文本文件的最佳方法
【发布时间】:2011-02-28 20:30:41
【问题描述】:

我有一个大约 100,000 行 (5 MB) 的文本文件,每天更新一次。它以每天大约 30 条线的速度增长。这些行没有以任何方式排序。每行 50 个十六进制字符长,如下所示:

ABCDE9DAF1F66C10C02F25A1685821F8428422F5870F39A3FE

给定这些字符串之一,我需要确定它是否存在于该文件中。我正在手持设备上使用 C# (.NET CF 2.0),因此内存有限。我有能力在 Windows 服务器上事先处理文件。最快的方法是什么?我最初的一些想法包括:对文件进行排序、逐行比较字符串、创建要搜索的二进制文件或使用 SQLite。

来自 OP 的 cmets(一个重要的问题,最初被排除在问题之外):

该文件是只读的。不会有任何改变 永远由我的程序制作。我得到一个 每天都有新版本的文件 更多的字符串追加到末尾

【问题讨论】:

  • 您可以通过将字符串视为整数来将文件大小减半。既然您正在寻找“最佳”,那么字符串是否有任何分布?例如,以“A”开头的字符串是否比以“E”开头的字符串出现的频率更高……
  • 字符串长度为 100 位,如何将它们视为整数?我不知道将来可以将哪些字符串添加到文件中,所以我不想设计一种聪明的搜索技术,它依赖于未来几个月可能发生变化的某个分布。
  • ABCD 将 4 个字节作为字符串,但将 2 个字节作为整数,但您似乎已经以这种方式存储它们,因为您谈论的是 100 位,而不是 200 位。

标签: c# .net algorithm performance string


【解决方案1】:

执行此操作的最佳方法可能是在服务器上对文件进行预排序,并使用内存映射文件对文件进行二进制搜索。话虽如此,.NET CF 2.0 将不支持内存映射文件。

您最好只对文件进行预排序,然后使用流访问对文件执行二进制搜索。这不是很好,因为您没有顺序读取,但是看到您在 CF 上,您设备上的数据存储很可能是基于闪存的,因此二进制搜索的随机访问可能不会太不好...

【讨论】:

    【解决方案2】:

    在服务器上保持文件排序((c) LorenVS),但直接对文件进行二进制搜索,使用记录长度(50 个十六进制字符 + 2 个用于 Cr Lf)将文件指针(seek)移动到中间位置并读取要比较的字符串。这应该可以最大限度地减少设备所需的内存。

    好的,我现在看到这个想法的第二部分也是 (c) LorenVS。

    【讨论】:

    • 嗯,我应该提到的是,因为数据是固定长度的,所以你可以计算绝对偏移量,所以很高兴你提到它
    【解决方案3】:

    将数据存储在 base-256 DAWG 中 - 您将获得相当紧凑的数据表示和快速搜索。

    【讨论】:

      【解决方案4】:

      如果您的应用程序正在运行并且必须防止将重复的字符串附加到现有文件中,您可以将整个文件内容保存在内存中的哈希表或排序列表中。当您启动您的应用程序时,您可以在另一个线程中优化此集合的加载,以保持您的 UI 响应。

      考虑一下,即使使用 SQLite 或 SQL CE,您也拥有嵌入式数据库的足迹,我认为现在 5 Mb 已经不再吓到任何人了。

      【讨论】:

      • 该文件是只读的。我的程序不会做出任何改变。我每天都会收到一个新版本的文件,末尾附加了更多字符串。
      【解决方案5】:

      已经有一些对文件排序的建议。

      另一个想法可能是将主文件保持在未排序的顺序,并使用辅助文件来检查重复项。

      具有使用小散列值和固定数量的偏移值的格式。哈希值是辅助文件中的偏移量。从该偏移量是主文件中的偏移量数组。当任何哈希数组填满时,您需要使用更大的哈希值和更大的辅助文件重新计算。或者你可以使用一些技巧,比如cuckoo hash

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-10
        • 2018-03-07
        • 2020-12-11
        • 2021-12-10
        • 2011-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多