【问题标题】:How can I improve performance of string processing with less memory?如何以更少的内存提高字符串处理的性能?
【发布时间】:2012-10-21 06:43:56
【问题描述】:

我正在用 Java 实现它。

Symbol file     Store data file

1\item1         10\storename1
10\item20       15\storename6
11\item6        15\storename9
15\item14       1\storename250
5\item5         1\storename15

用户将使用诸如storename? 之类的通配符搜索商店名称 我的工作是搜索商店名称并使用符号数据生成完整的字符串。例如:

item20-storename1
item14-商店名称6
item14-storename9

我的做法是:

  1. 逐行读取存储数据文件
  2. 如果任何一行包含匹​​配的搜索字符串(如storename?),我会将该行推送到中间存储结果文件
  3. 我还将匹配商店名称的 itemno 复制到数组列表中(如 10,15)
  4. 当这个 arraylist size%100==0 时,我将使用 hashset 删除重复的项目号,从而显着减小 arraylist 大小
  5. 当数组列表大小>1000

    1. 使用Collections.sort(itemno_arraylist)对该列表进行排序
    2. 打开符号文件并开始逐行读取
    3. 对于每一行Collections.binarySearch(itemno_arraylist,itmeno)
    4. 如果匹配则将结果推送到中间符号结果文件
  6. 继续执行步骤 1,直到存储数据文件的 EOF

...

在所有这些之后,我将结合两个结果文件(符号结果文件和存储结果文件)来呈现实际的字符串列表。

这种方法是有效的,但它会消耗更多的 CPU 时间和主内存。

我想知道一个更好的解决方案,减少 CPU 时间(当前为 2 分钟)和内存(当前为 80MB)。 Java 中有许多可用的集合类。哪一个会为这种巨大的字符串处理问题提供更有效的解决方案?

如果您对 Java 中的此类字符串处理问题有任何想法,那将会非常有用。

注意:这两个文件的长度接近一百万行。

【问题讨论】:

  • 您的数据文件是静态的还是经常变化的?
  • @Yogendra Singh 是的,它会改变,但不会频繁
  • 为解决此类问题创建了数据库,你知道吗?

标签: java string performance collections


【解决方案1】:

用嵌入式数据库替换这两个平面文件(有plenty of them,我过去使用SQLite 和Db4O):问题解决了。

【讨论】:

    【解决方案2】:

    因此您需要将10\storename1 替换为item20-storename1,因为符号文件包含10\item20。显而易见的解决方案是将符号文件加载到 Map 中:

    String tokens=symbolFile.readLine().split("\\");
    map.put(tokens[0], tokens[1]);
    

    然后逐行读取存储文件并替换:

    String tokens=storelFile.readLine().split("\\");
    output.println(map.get(tokens[0])+'-'+tokens[1]));
    

    这是最快的方法,但仍会为地图使用大量内存。您可以减少将地图存储在数据库中的内存,但这会显着增加时间。

    【讨论】:

      【解决方案3】:

      如果您的输入数据文件不经常更改,则解析文件一次,将数据放入自定义类的List,例如FileStoreRecord 将您的记录映射到文件中。在自定义类上定义 equals 方法。在List 上执行所有后续步骤,例如对于搜索,您可以通过以自定义对象FileStoreRecord 的形式传递搜索字符串来调用contains 方法。

      如果文件在一段时间后发生变化,您可能需要在一定间隔后刷新List,或跟踪列表创建时间并在使用前与文件更新时间戳进行比较。如果有不同,请重新创建列表。管理文件检查的另一种方法是让 Thread 不断轮询文件更新,并在文件更新时通知刷新列表。

      【讨论】:

      • 我不认为这会很好,因为它只是一个更大的内部数组。请注意,OP 不会通过 s1.equals(s2) 搜索访问元素。
      【解决方案4】:

      使用地图有什么限制吗? 您可以将项目添加到地图,然后您可以轻松搜索? 100万条记录意味着1M * recordSize,所以不会有问题。

         Map<Integer,Item> itemMap= new HashMap();
         ...
         Item item= itemMap.get(store.getItemNo());
      

      但是,最好的解决方案是使用数据库。

      【讨论】:

        猜你喜欢
        • 2021-10-21
        • 1970-01-01
        • 1970-01-01
        • 2019-09-14
        • 2012-09-09
        • 1970-01-01
        • 1970-01-01
        • 2016-05-15
        • 2018-07-11
        相关资源
        最近更新 更多