如何使用42,000个密钥优化此HashMap

时间:2015-05-07 01:53:07

标签: java arrays hashmap

我有一个csv文件,其中42,000行采用以下模式

03055,Milford,NH
03057,Mont Vernon,NH
03060,Nashua,NH

我尝试使用zipcode作为密钥将数据存储在HashMap中,例如

while ((line = stream_in.readLine())!=null) {
    LocationBean temp_location_bean = new LocationBean();
    String line_trimmed = line.trim();
    String[] line_chunked = line_trimmed.split(",",4);
    temp_location_bean.setZip_code(line_chunked[0]);
    temp_location_bean.setCity(line_chunked[1]);
    temp_location_bean.setState(line_chunked[2]);
    this.locations_as_beans_list.put(zip_code, temp_location_bean);
}

但是当我去查找时:

 for(Map.Entry<String, LocationBean> location_object : this.locations_as_beans_list.entrySet())
 {
     LocationBean temp_location_bean = location_object.getValue();
     if (params[0].matches(temp_location_bean.getZip_code())) {
         master_location = temp_location_bean.getCity() + "," 
             + temp_location_bean.getState()
             + ", (" + temp_location_bean.getZip_code() +")";
     }
 }

需要20多秒......性能不应该相对较快吗?我怎样才能提高性能呢?

TL;博士 如何在此示例中优化读取?

5 个答案:

答案 0 :(得分:5)

如果您正在寻找性能,那么您不应该迭代entrySet来查找带密码的邮政编码。相反,您可以使用HashMap并通过其&#39;来获取值。键。像,

LocationBean temp_location_bean = this.locations_as_beans_list.get(params[0]);
if (temp_location_bean != null) {
    master_location = temp_location_bean.getCity() + "," 
            + temp_location_bean.getState() 
            + ", (" + temp_location_bean.getZip_code() +")";
}

答案 1 :(得分:4)

您可以通过多种方式实现性能优化。 这里的问题不在于您是否可以通过数据结构或数据元素或数据解析来实现它。

当优化进入画面时,你应该记住各种观点,实现性能提升是最关键的问题之一。

<强> 1。阅读文件 - BufferedReader将花费6/7 seconds to parse 878 MB file的恒定时间。你怎么能减少它?

a。您可以浏览RandomAccessChannel API in java,将同一档案的缩减为0.16 / 0.19秒。

b。 Asynchronous File Reads在特定文件上。

<强> 2。处理数据处理

a。使用运行时可用的处理器API,您可以获得特定计算机上可用的处理器数量,并产生许多线程以进行数据处理。

b。多线程游戏在实现绩效方面发挥着重要作用

上面提到的几点是你可以花时间来减少表演

答案 2 :(得分:4)

问题中描述的方法的基本问题是,迭代地图并将每个条目与查询字段进行比较。这是错的。 HashMaps主要不适用于迭代,并且针对基于密钥的搜索进行了优化。因此,快速获得性能的最简单方法是使用key并使用HashMap的get方法直接检索值(注意,密钥是经过哈希处理的,因此使用密钥调用get方法将启用快速查找)。

如果您想再采取一个步骤,您应该寻找像Javolution这样的专业库。该库确保不是为HashMap中的每个项创建EntrySet,而只是使用散列键存储条目。这样可以显着提高内存和性能(没有为每个条目创建新对象)。

答案 3 :(得分:1)

如果需要使用基于正则表达式的查找,HashMap不是正确的数据结构。可以选择列表,因为您必须使用正则表达式来匹配循环中的元素。

我的建议:

您可以将大数据集拆分为多个列表,并使用多线程分别搜索列表,并收集结果。

PLUS:我认为MapReduce在一台机器上处理40k数据有点重。

答案 4 :(得分:0)


这里有几点建议 -

A.使用像Sharding这样的东西 - 将数据分成几个地图,运行线程并收集结果(在MapReduce中将其视为一个很好的练习

B.比赛 - 为什么使用比赛?那里有性能打击。
你真的需要使用通用的东西吗?为匹配算法编写更具体的代码

C.在您的EntrySet循环中,您在哪里使用getKey()?为什么不只是对值进行迭代(查看this method