Java Arraylist to Map速度比较

标签 java arraylist foreach parallel-processing

我正在尝试将 ArrayList 转换为 Treemap,因此我编写了一种基准来比较各种方法:

1) 并行流中的toMap

2) 流中的toMap

3) forEach 在流中

4) forEach 并行流

5) 循环

如果 ArrayList 大小很小(比如 10,000),一切都很好,但是当大小很大时,比如一百万,即使在 9 分钟后它仍在运行“forEach Parallel Stream”方法。我用 try catch 包围了它,但它很干净。

我知道创建新线程会有一些开销,但是 parallelStream 使用 threadPool 所以它应该很低,对吧?

public class Set {
private String foo;
private int bar;

public Set(String foo, int bar) {
    this.foo = foo;
    this.bar = bar;
}

public String getFoo() {
    return foo;
}

public void setFoo(String foo) {
    this.foo = foo;
}

public int getBar() {
    return bar;
}

public void setBar(int bar) {
    this.bar = bar;
}

}

主要

public class Test {
TreeMap tr=new TreeMap();

public static void main(String[] args) {
    Test t = new Test();
    t.g();
}

public void g(){
    ArrayList<Set> ar=new ArrayList<>();
    for (int i = 0; i < 1_000_000; i++) {
        ar.add(new Set(UUID.randomUUID().toString(), new Random().nextInt()));
    }
    long start;
    long end;
    System.out.println("Parallel toMap");
    start=System.nanoTime();
    tr.putAll(ar.parallelStream().collect(Collectors.toMap(Set::getFoo, Set::getBar)));
    end=System.nanoTime();
    System.out.println(end-start);

    tr=new TreeMap();
    System.out.println("non-Parallel toMap");
    start=System.nanoTime();
    tr.putAll(ar.stream().collect(Collectors.toMap(Set::getFoo, Set::getBar)));
    end=System.nanoTime();
    System.out.println(end-start);

    tr=new TreeMap();
    System.out.println("non-Parallel forEach");
    start=System.nanoTime();
    ar.stream().forEach(product -> {
            tr.put(product.getFoo(), product.getBar());
        });
    end=System.nanoTime();
    System.out.println(end-start);

    tr=new TreeMap();
    System.out.println("Parallel forEach");
    start=System.nanoTime();
//HANGS SOMEWHERE HERE
    ar.parallelStream().forEach(product -> {
        try {
            tr.put(product.getFoo(), product.getBar());
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }

        });
    end=System.nanoTime();
    System.out.println(end-start);

    tr=new TreeMap();
    System.out.println("non-Parallel loop");
    start=System.nanoTime();
    for(Set product:ar)
        tr.put(product.getFoo(), product.getBar());

    end=System.nanoTime();
    System.out.println(end-start);
    }
}

大小为 10_000 的输出如下

Parallel toMap
130793206
non-Parallel toMap
21729202
non-Parallel forEach
7601349
Parallel forEach
3233395
non-Parallel loop
9744039

“for 循环”是预期中最慢的

'paralled forEach' 比预期的'non-parallel forEach' 更快

“平行于 map ”比“非平行于 map ”慢 5 倍??什么?英特尔睿频加速发挥作用?

回到为什么当 arraylist 列表很大时“forEach in parallel steam”会失败?

运行 i7 2670QM,所以线程池大小应该是 8

最佳答案

TreeMap 不是线程安全的。因此,当从多个线程使用它时,所有的赌注都被取消了。你可以在 HashMap 中得到一个无限循环。据推测,TreeMap 在某些方面表现得很糟糕。

(关于基准测试:由于 JVM 的“预热”方式,您应该为每个测试启动一个新进程。还要在一个进程中连续多次运行测试。)

关于Java Arraylist to Map速度比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30889900/

相关文章:

java - EventHandler 作为匿名内部类实现

java - Java 中的 toString 覆盖

使用 JPanel 部署 Java 组件

java - 使用通用函数根据 ArrayList 中的索引对 HashMap 进行排序

JavaScript:根据条件创建二维对象数组

php - 为 foreach 提供的参数无效

java - ANDROID: If...Else 作为 Switch on String

java - 如何从java swing中的多个文本框中获取值

java - 从使用外部类的 ArrayList 获取变量

php - 当我使用 while 循环时,如何获取每个输入文本的单独值?