java - 如何使用多线程使我的应用程序更快

标签 java multithreading list concurrency hashset

我正在遍历包含 +- 1500 个条目的字符串列表。在每次迭代中,我再次遍历字符串列表,但这次有 +- 3500 万个条目。应用的结果是完美的。但是应用程序需要很长时间(2 个多小时)才能给我结果。我应该如何构造多线程以使我的应用程序更快?

结果列表的顺序并不重要。

  • 我是否应该将大列表(3500 万个条目)分成较小的 block 并并行迭代它们? (我怎样才能确定 block 的完美数量?)
  • 我应该为小列表中的每个迭代启动一个线程吗? (这将创建 1500 个线程,我猜其中很多线程将“并行”运行)

我还有哪些其他选择?

代码表示:

List<String> result = new ArrayList<String>();
for(Iterator<String> i = data1.iterator();i.hasNext();){ //1500 entries
  String val = i.next();
  for(Iterator<String> j = data2.iterator();j.hasNext();){ //35 million entries
    String test = j.next();
    if(val.equals(test)){
      result.add(val);
      break;
    }
  }
}
for(Iterator<String> h = result.iterator();h.hasNext();){
  //write to file
}

更新

在重组我的代码并实现 JB Nizet 给出的答案后,我的应用程序现在运行得更快了。现在只需 20 秒即可获得相同的结果!没有多线程!

最佳答案

您可以使用并行流:

List<String> result = 
    data1.parallelStream()
         .filter(data2::contains)
         .collect(Collectors.toList());

但是由于您在 data2 上调用了 contains() 1500 次,并且由于 contains() 对于列表来说是 O(N),首先将其转换为 HashSet 可以使事情变得更快:HashSet 上的 contains() 是 O(1)。您甚至可能不再需要多线程:

Set<String> data2Set = new HashSet<>(data2);
List<String> result = 
    data.stream()
        .filter(data2Set::contains)
        .collect(Collectors.toList());

关于java - 如何使用多线程使我的应用程序更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48967411/

相关文章:

list - Haskell 递增元组的最后一个元素

java - 将指向外部互联网站点的超文本链接放入 javadoc

c++ - 为什么即使在使用 Qt::DirectConnection 之后,接收方的线程中仍会调用插槽?我如何确保它在另一个线程中被调用?

java - 无法创建 Java VM --- 如何获得更详细的错误消息?

c++ std::thread 调用方法从对象原因到调用此类的析构函数

c++ - 在执行过程中休眠一个线程

python - 字典组成和通过列表条目更新值

python - 错误反转():list is not callable

java - Spring Boot 升级错误 - 名称为 org.springframework.transaction.config.internalTransactionalEventListenerFactory 的无效 bean 定义

java - Oracle JDBC 驱动程序未在遗留 Web 应用程序中使用 JNDI 连接到数据库