首页 > 解决方案 > java.time.ZonedDateTime 与 java.util.Calendar 性能检查

问题描述

我试图获得月份价值。但我想检查哪个更好,java.util 或 java.time 来检索月份值。这是我检查 Calender 与 ZonedDateTime 性能的代码。

    //import java.time.Instant;
    //import java.time.ZonedDateTime;
    //import java.util.Calendar;

    Instant instant, instant2; 
    String diff;

    instant = Instant.now();
    int month2 = Calendar.getInstance().get(Calendar.MONTH) + 1;
    instant2 = Instant.now();
    diff = String.valueOf(instant2.getNano() - instant.getNano());
    System.out.println("month value " + month2 + "at: " + diff);

    instant = Instant.now();
    int month1 = ZonedDateTime.now().getMonth().getValue();
    instant2 = Instant.now();
    diff = String.valueOf(instant2.getNano() - instant.getNano());
    System.out.println("month value " + month1 + "at: " + diff);

我认为 java.time 比 java.util 更好。因此,我期望 ZonedDateTime 比 Calendar 表现更好。但在这里我发现了相反的情况。我的结果是:

month value 6at: 0  //Calendar
month value 6at: 9000000 //ZonedDateTime

任何想法为什么会发生这种情况。以及为什么我应该使用 java.util.Calender 而不是 java.timeZonedDateTime 的任何建议。

PS 我什至在第 1 个月之后将第 2 个月的检索结果反转为:

    Instant instant, instant2; 
    String diff;

    instant = Instant.now();
    int month1 = ZonedDateTime.now().getMonth().getValue();
    instant2 = Instant.now();
    diff = String.valueOf(instant2.getNano() - instant.getNano());
    System.out.println("month value " + month1 + "at: " + diff);

    instant = Instant.now();
    int month2 = Calendar.getInstance().get(Calendar.MONTH) + 1;
    instant2 = Instant.now();
    diff = String.valueOf(instant2.getNano() - instant.getNano());
    System.out.println("month value " + month2 + "at: " + diff);

还是一样:

month value 6at: 8000000   //ZonedDateTime
month value 6at: 0  //Calendar

标签: javaperformancedatezoneddatetimejava.util.calendar

解决方案


java.time的设计目标包括清晰和预期的行为、不可变对象、线程安全、标准的利用以及许多其他点。目标包括比旧的日期时间类(包括Calendar. 此外,虽然我听到很多关于旧课程的抱怨,但我没有听到过他们表现太差的抱怨。

如果现代 API 的卓越设计在某些情况下会导致性能损失,我认为我们不应该感到惊讶或担心。

不过,您的测量结果并不可靠。进行正确的基准测试比这更复杂。我也做了一些不可靠的测量:在我的电脑上,我只得到了 124 178 930 纳秒Calendar和 66 794 865 纳秒ZonedDateTime,大约一半,System.nanoTime()用于测量。YearMonth.now().getMonthValue()(也来自 java.time)仅在 8 339 306 场演出,大约是日历的 15 分之一(1/15)。

对于 99.5% 的情况,仅对于Calendar您必须将月份值加 1 并且读者需要了解为什么要加 1 的事实,比性能更重要。

当然,如果在您的特定系统中存在性能瓶颈,并且可信赖的测量结果告诉您,将您的一种方法切换为 using CalendarTime4JJoda-Time、某些 Apache 库或某些 C 代码将解决该问题,这是一个完全正当的理由这样做。我很难想象会是这样,但话又说回来,我不知道世界上所有的计算机系统。

链接


推荐阅读