如何以更少的内存提高字符串处理的性能?

时间:2012-10-21 06:43:56

标签: java string performance collections

我在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-storename6
item14-storename9

我的方法是:

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

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

  7. ...

    在完成所有这些后,我将两个结果文件(符号结果文件和存储结果文件)组合在一起,以显示实际的字符串列表。

    这种方法正在运行,但它占用了更多的CPU时间和主内存。

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

    如果您对这种字符串处理问题有任何想法,那么Java中的这些问题也会非常有用并且很有帮助。

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

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

因此,您需要将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]));

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

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

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