在迭代中使用LambdaJ的效率明显不足



在使用JSF和JPA的java ee应用程序中,我必须计算对象列表中的属性总数。我使用了LambdaJ库来实现求和的计算。

由于我在应用程序的几个地方使用这种类型的总结,可能会对整体性能产生影响,因此我设计了以下测试java应用程序来测试LambdaJ的有效性。

这个应用程序显示了LambdaJ的有效性明显不足。

测试程序中是否有任何错误,或者我是否应该用迭代替换所有lambdaJ的出现?

结果

Time taken to calculate a single total by iteration is 15 milliseconds.
Time taken to calculate a single total by LambdaJ is 199 milliseconds.
Time taken to calculate multiple totals by iteration is 23 milliseconds.
Time taken to calculate multiple totals by LambdaJ is 114 milliseconds.

Main Method

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.lakmedi;
import ch.lambdaj.Lambda;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
/**
 *
 * @author buddhika
 */
public class main {
    public static void main(String[] args) {
        List<Bill> bills = new ArrayList<>();
        Random r = new Random();
        for (int i = 0; i < 100000; i++) {
            Bill b = new Bill();
            b.setGrossTotal(r.nextDouble());
            b.setDiscount(r.nextDouble());
            b.setNetTotal(b.getGrossTotal() - b.getDiscount());
            bills.add(b);
        }
        calSingleByIteration(bills);
        calSingleByLambdja(bills);
        calMultipleByIteration(bills);
        calMultipleByLambdja(bills);
    }
    public static void calSingleByIteration(List<Bill> bills) {
        Date startTime = new Date();
        double grossTotal = 0.0;
        for (Bill b : bills) {
            grossTotal += b.getGrossTotal();
        }
        Date endTime = new Date();
        long timeTaken = endTime.getTime() - startTime.getTime();
        System.out.println("Time taken to calculate a single total by iteration is " + timeTaken + " milliseconds.");
    }
    public static void calSingleByLambdja(List<Bill> bills) {
        Date startTime = new Date();
        double grossTotal = Lambda.sumFrom(bills).getGrossTotal();
        Date endTime = new Date();
        long timeTaken = endTime.getTime() - startTime.getTime();
        System.out.println("Time taken to calculate a single total by LambdaJ is " + timeTaken + " milliseconds.");
    }
    public static void calMultipleByIteration(List<Bill> bills) {
        Date startTime = new Date();
        double grossTotal = 0.0;
        double discount = 0.0;
        double netTotal = 0.0;
        for (Bill b : bills) {
            grossTotal += b.getGrossTotal();
            discount += b.getDiscount();
            netTotal += b.getNetTotal();
        }
        Date endTime = new Date();
        long timeTaken = endTime.getTime() - startTime.getTime();
        System.out.println("Time taken to calculate multiple totals by iteration is " + timeTaken + " milliseconds.");
    }
    public static void calMultipleByLambdja(List<Bill> bills) {
        Date startTime = new Date();
        double grossTotal = Lambda.sumFrom(bills).getGrossTotal();
        double discount = Lambda.sumFrom(bills).getDiscount();
        double netTotal = Lambda.sumFrom(bills).getNetTotal();
        Date endTime = new Date();
        long timeTaken = endTime.getTime() - startTime.getTime();
        System.out.println("Time taken to calculate multiple totals by LambdaJ is " + timeTaken + " milliseconds.");
    }
}

Bill类

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.lakmedi;
/**
 *
 * @author buddhika
 */
public class Bill {
    private double grossTotal;
    private double netTotal;
    private double discount;
    public double getGrossTotal() {
        return grossTotal;
    }
    public void setGrossTotal(double grossTotal) {
        this.grossTotal = grossTotal;
    }
    public double getNetTotal() {
        return netTotal;
    }
    public void setNetTotal(double netTotal) {
        this.netTotal = netTotal;
    }
    public double getDiscount() {
        return discount;
    }
    public void setDiscount(double discount) {
        this.discount = discount;
    }

}

假设您指的是效率而不是功效,那么您测量的性能或多或少符合预期——参见LambdaJ自己的性能分析。

使用Java 8 Lambda Expressions可能会得到更好的结果,但这里的主要目标是提高源代码的可读性和可维护性,而不是速度。您确定执行求和所需的时间对应用程序的整体性能至关重要吗?考虑到http流量(JSF)和数据库查询(JPA)的(I/O)等待时间,我对此表示怀疑,在这种情况下,这是过早的优化(所有罪恶的根源)。

首先,检查您使用的是最新版本的LambdaJ,因为项目站点表明最新版本有一些性能改进。

然而,我认为你应该期望lambdaj比编写等效的for循环慢。在更简洁的语法背后,JVM做了更多的工作。

你可以考虑放弃lambdaj而使用Java 8流和lambda表达式。

以下是lambdaj的作者对此事的看法:

让我再澄清一次:在Java8发布之后,我认为开发/维护#lambdaj没有任何意义。迁移到Java8 &快乐

——Mario Fusco, 2014年5月

相关内容

  • 没有找到相关文章

最新更新