0

JSF と JPA を使用する Java ee アプリケーションでは、オブジェクトのリスト内の属性の合計を計算する必要があります。合計の計算を行うために LambdaJ ライブラリを使用しました。

この種の合計をアプリケーションのいくつかの場所で使用し、全体的なパフォーマンスに影響を与える可能性があるため、LambdaJ の有効性をテストするために次のテスト Java アプリケーションを設計しました。

このアプリケーションは、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.

主な方法

/*
 * 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.");
    }

}

お札クラス

/*
 * 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;
    }


}
4

2 に答える 2

3

有効性ではなく効率性を意味すると仮定すると、測定されたパフォーマンスは多かれ少なかれ予想どおりです - LambdaJ 自身のパフォーマンス分析を参照してください。

Java 8 Lambda Expressionsを使用すると、より良い結果が得られる可能性がありますが、ここでの主な目標は、速度ではなく、ソース コードの読みやすさと保守性を向上させることです。合計の実行に必要な時間が、アプリケーションの全体的なパフォーマンスにとって重要であると確信していますか? HTTP トラフィック (JSF) およびデータベース クエリ (JPA) の (I/O) 待機時間を考慮すると、これは時期尚早の最適化(すべての悪の根源) であるとは思えません。

于 2014-08-17T00:08:10.553 に答える
2

まず、最新バージョンの LambdaJ を使用していることを確認します。これは、プロジェクト サイトで、最近のバージョンではパフォーマンスが改善されていることが示されているためです。

ただし、lambdaj は、同等の for ループを記述するよりも遅いと予想する必要があると思います。より簡潔な構文の背後で、JVM はさらに多くの作業を行っています。

ラムダジを削除し、Java 8 ストリームとラムダ式を使用することを検討できます。

lambdaj の作成者は、この問題について次のように述べています。

これをもう一度明確にします。Java8 のリリース後、#lambdaj を開発/維持する意味がわかりません。Java8 に移行して幸せになろう

--マリオ フスコ、2014 年 5 月

于 2014-08-17T00:09:37.703 に答える