gpt4 book ai didi

java - 使用 Java 8 的整数列表的总和

转载 作者:搜寻专家 更新时间:2023-11-01 01:12:55 26 4
gpt4 key购买 nike

我只是在玩弄 Java 8,并使用程序计算大型列表中偶数的总和,将一些事情与 Java 6 进行了比较

Java 8

public class ListOperationsJava8 {

static List<BigInteger> list = new LinkedList<>();

public static void main(String[] args) {
createList();

long start = System.currentTimeMillis();

/*System.out.println(list.parallelStream().
filter(n -> n.mod(new BigInteger("2")).equals(BigInteger.ZERO)).
mapToInt(BigInteger::intValue).sum()); --> gives result -1795017296 */

System.out.println(list.parallelStream().
filter(n -> n.mod(new BigInteger("2")).equals(BigInteger.ZERO)).
mapToLong(BigInteger::longValue).sum());

long end = System.currentTimeMillis();

System.out.println("Time taken using Java 8: " + (end - start) + " ms");
}

private static void createList() {
for (int i = 0; i < 100000; i++) {
list.add(new BigInteger(String.valueOf(i)));
}
}
}

Java 6

public class ListOperationsClassic {

static List<BigInteger> list = new LinkedList<BigInteger>();

public static void main(String[] args) {
createList();

long start = System.currentTimeMillis();

BigInteger sum = BigInteger.ZERO;

for(BigInteger n : list) {
if(n.mod(new BigInteger("2")).equals(BigInteger.ZERO))
sum = sum.add(n);
}

System.out.println(sum);

long end = System.currentTimeMillis();

System.out.println("Time taken using Java 6: " + (end - start) + " ms");
}

private static void createList() {
for (int i = 0; i < 100000; i++) {
list.add(new BigInteger(String.valueOf(i)));
}
}
}

我有两个问题

  1. 在 Java 8 代码中,最初我使用mapToInt(BigInteger::intValue).sum()) 减少值,但是得到了否定结果 -1795017296!为什么?预期结果 2499950000本身在一个 int 可以表示的范围内,因为我明白。
  2. 我多次运行代码,总能找到 Java 8 中的代码花费的时间比使用 Java 6 的代码多 5 倍。那是什么可能是什么意思对于这种规模的操作,不值得使用parallelStream 和/或 reduce 操作和普通的旧 for 循环更好吗?

这是其中一个结果:

2499950000
Time taken using Java 6: 52 ms

2499950000
Time taken using Java 8: 249 ms

最佳答案

这是我的快速基准测试,允许在每次测试之间进行 JIT 预热和 GC。结果:

  • for 循环:686 毫秒
  • lamdbda:681 毫秒
  • 并行 lambda:405 毫秒

请注意,我已经修改了您的代码,使三个测试尽可能等效 - 特别是对于 lambda,我使用归约来添加 BigIntegers 而不是转换为 long。
我还删除了每次迭代时不必要的 new BigInteger("2") 创建。

public class Test1 {

static List<BigInteger> list = new LinkedList<>();
static BigInteger TWO = new BigInteger("2");

public static void main(String[] args) {
createList();

long sum = 0;

//warm-up
for (int i = 0; i < 100; i++) {
sum += forLoop().longValue();
sum += lambda().longValue();
sum += parallelLambda().longValue();
}

{
System.gc();
long start = System.currentTimeMillis();
for (int i = 0; i < 100; i++) sum += forLoop().longValue();
long end = System.currentTimeMillis();
System.out.println("Time taken using for loop: " + (end - start) + " ms");
}

{
System.gc();
long start = System.currentTimeMillis();
for (int i = 0; i < 100; i++) sum += lambda().longValue();
long end = System.currentTimeMillis();
System.out.println("Time taken using lambda: " + (end - start) + " ms");
}

{
System.gc();
long start = System.currentTimeMillis();
for (int i = 0; i < 100; i++) sum += parallelLambda().longValue();
long end = System.currentTimeMillis();
System.out.println("Time taken using parallelLambda: " + (end - start) + " ms");
}
}

private static void createList() {
for (int i = 0; i < 100000; i++) {
list.add(new BigInteger(String.valueOf(i)));
}
}

private static BigInteger forLoop() {
BigInteger sum = BigInteger.ZERO;

for(BigInteger n : list) {
if(n.mod(TWO).equals(BigInteger.ZERO))
sum = sum.add(n);
}
return sum;
}

private static BigInteger lambda() {
return list.stream().
filter(n -> n.mod(TWO).equals(ZERO)).
reduce(ZERO, BigInteger::add);
}

private static BigInteger parallelLambda() {
return list.parallelStream().
filter(n -> n.mod(TWO).equals(ZERO)).
reduce(ZERO, BigInteger::add);
}
}

关于java - 使用 Java 8 的整数列表的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21940693/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com