当前位置: 首页 > 知识库问答 >
问题:

我对Java 8 lambda谓词做错了什么?[副本]

梁丘招
2023-03-14

这不是重复我的问题。我检查了它,我的是如何使用正确的谓词,这是关于removeIf和remove之间的区别。

我是Java程序员的初学者。
昨天,我试着学习了这篇教程https://dzone.com/articles/why-we-need-lambda-expressions
在学习了如何使用Lambda表达式和谓词之后,我制作了自己的代码来练习。
比如,如果(n%3==0n%5==0)和所有的数字。这是我的代码。

public class Euler1Lambda {
    long max;
    public Euler1Lambda(long max) {
        this.max = max;
    }
public static boolean div3remainder0(int number) {
    return number % 3 == 0;
}

public static boolean div5remainder0(int number) {
    return number % 5 == 0;
}

public long sumAll() {
    long sum = 0;
    for(int i=1; i<max; i++) {
        if (div3remainder0(i) ||div5remainder0(i)) {
            sum += i;
        }
    }
    return sum;
}

public long sumAllLambda(Predicate<Integer> p) {
    long total = 0;
    for (int i = 1; i< max; i++){
        if (p.test(i)) {
            total += i;
        }
    }
return total;
}

public static void main(String[] args) {
    //conv
    long startTime = System.currentTimeMillis();
    for(int i = 0; i < 10; i++){
        new Euler1Lambda(100000000).sumAll();
    }
    long endTime = System.currentTimeMillis();
    long conv = (endTime - startTime);
    System.out.println("Total execution time: " + conv);
    //lambda
    startTime = System.currentTimeMillis();
    for(int i = 0; i < 10; i++){
        new Euler1Lambda(100000000).sumAllLambda(n -> div3remainder0(n) || div5remainder0(n));
    }
    endTime = System.currentTimeMillis();
    long lambda = (endTime - startTime);
    System.out.println("Total execution time: " + lambda);
    System.out.println("lambda / conv : " + (float)lambda/conv);
}
}

在这段代码中,做了时序测试。结果如下所示。

Total execution time conv: 1761
Total execution time lambda: 3266

lambda / conv : 1.8546281

正如您所看到的,带有谓词的lambda表达式比简单的for-loop慢。
我不知道为什么结果会这样。
我做错了什么?还是仅仅使用谓词的方式太慢?

共有1个答案

易炳
2023-03-14

首先,我们来看看事情的尺度。您说的是100000000个项目的差值约为1505毫秒,或每个项目约为15纳秒。开销不是很大。

也就是说,开销是为了谓词 而将所有int自动装箱为integer谓词::test采用整数,因此p.test(i)实际上被编译为p.test(integer.valueof(i))。这种方法并不是非常昂贵,但也不是免费的。显然在你的电脑上需要15纳秒。

如果您改用intPredicate(它使用int基元作为输入,从而避免装箱),您会发现直接方法和基于lambda的方法之间的区别实际上已经消失了。

除此之外,在Java还有一些关于微基准测试的常见警告(预热循环,使用像JMH这样的框架等)。关于这个主题有很多的知识,如果你想继续像这样对快速行动进行基准测试的话,我强烈地鼓励你去阅读它。

 类似资料:
  • 我正在做一个项目,我的意图是运行一个玉米作业,并发送邮件给我的朋友,祝他们生日,我能够从MySQL DB获取电子邮件,并将其与当前日期进行比较,但当涉及到发送电子邮件时,我得到NullPointerException。 我确信应用程序属性没有问题,我在其他项目中也使用了它们,它们的功能正常 这是我得到以下信息的错误

  • 我不知道我在这里有什么错误,但它不会编译。我得到的错误消息是/"fe"而没有"if"/ /not一个语句//没有"if"/ 我正在按照我作业中的样本所显示的方式来做,我仍然会遇到这个错误。请有人帮我学数学。PI。我完全迷路了。

  • 11:15:57创建表如果不存在tblcompany(companyid INT(11)无符号NOT NULL,custfirst VARCHAR(50),custlast VARCHAR(50),company VARCHAR(50),custphone VARCHAR(50), custemail VARCHAR(50),主键(companyid),索引(companyid),约束外键(com

  • 问题内容: 我有一些代码来计算圆的属性: 它计算周长,但不计算其余部分。 问题答案: 是一个,也一个,这意味着不能在第二个打印语句中使用。试试那里。 回想一下,这是浮点数,而整数。在的文档中对此进行了概述(请参阅“ 格式化字符串语法”)。

  • 我正在使用EclipseIDE编程。在完成有关Apache POI的教程后: https://www.youtube.com/watch?v=RsrF2Ku7ad4 我通过eclipse和以下链接创建了一个可执行jar:http://help.eclipse.org/mars/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/tasks-37.htm