有没有好的高性能java库可以与时间戳一起使用?

发布于 2024-11-17 03:09:41 字数 274 浏览 1 评论 0原文

我正在寻找高性能Java库,它提供的方法允许我获取:

  1. 当前小时(0-24)
  2. 当前日期(1-31)
  3. 当前星期(1-52)
  4. 当前月份(1-12)
  5. 当前季节(1- 4)
  6. 今年(YYYY 或 YY)

表现对我来说是最重要的问题。这就是为什么我不能使用标准日历类。最好的解决方案是在不创建新对象的情况下完成所有计算。

添加:为了澄清,我将再提一次:每秒超过 100000 次操作。

I am looking for high performance Java library that provides methods that allows me to get:

  1. Current hour (0-24)
  2. Current day (1-31)
  3. Current week (1-52)
  4. Current month (1-12)
  5. Current season (1-4)
  6. Current year (YYYY or YY)

Performance is a most important issue for me. This is why I cannot use standard Calendar class. The best would be solution that does all calculations without creating new objects.

ADDED: To clarify I will mention one more time: more that 100000 operations per second.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

蹲在坟头点根烟 2024-11-24 03:09:41

您实际上可以使用优秀的 joda-time 库来做到这一点。 joda 中的 Chronology 实现提供了 DateTime getHour getDay 类型方法背后的逻辑。如果您希望跳过创建 DateTime 瞬间,直接使用它是没有问题的。

long msSinceEpoch = System.currentTimeMillis();

Chronology chronology = ISOChronology.getInstanceUTC() // This can be static

chronology.hourOfDay().get(msSinceEpoch);
chronology.dayOfMonth().get(msSinceEpoch);
chronology.weekOfWeek().get(msSinceEpoch);
chronology.monthOfYear().get(msSinceEpoch);
chronology.years().get(msSinceEpoch);

Session不是joda有的概念。您必须根据自己的规则从当月开始计算。

请参阅有关年表的 joda-time 文档

You could actually use the excellant joda-time library to do this. The Chronology implementations in joda provide the logic behind the DateTime getHour getDay type methods. There is no problem using it directly if you wish to skip creating DateTime instants.

long msSinceEpoch = System.currentTimeMillis();

Chronology chronology = ISOChronology.getInstanceUTC() // This can be static

chronology.hourOfDay().get(msSinceEpoch);
chronology.dayOfMonth().get(msSinceEpoch);
chronology.weekOfWeek().get(msSinceEpoch);
chronology.monthOfYear().get(msSinceEpoch);
chronology.years().get(msSinceEpoch);

Session isn't something that joda has a concept of. You will have to work it out from the month given your own rules.

See joda-time documentation on Chronology

地狱即天堂 2024-11-24 03:09:41

您确定 Calendar 太慢还是您只是相信它?您测量了吗?

在 Java 中创建新对象非常便宜。保留它们的成本很高。

也就是说,要么尝试 Joda Time,要么将算法从 Java 代码复制到静态帮助器方法中。

Are you sure that Calendar is too slow or do you just believe it? Did you measure it?

Creating new objects in Java is pretty cheap. Keeping them around is expensive.

That said, either try Joda Time or copy the algorithms from the Java code into static helper methods.

哭了丶谁疼 2024-11-24 03:09:41

您可以获取当前时间并通过除法和余数计算出当前的小时、分、秒、毫秒。日、月、年每天仅更改一次,因此您只需在更改时进行计算。

您可以使用缓存的日/月/年并在亚微秒时间内计算其余部分,而无需创建对象(每天多次)

import java.util.Calendar;
import java.util.TimeZone;

public class Daytime {
    private static final long HOUR_MS = 3600*1000;

    public short year;
    public byte month, day;
    public byte hour, min, sec;
    public short millis;

    private long lastMillis = Integer.MIN_VALUE;
    private final TimeZone timeZone;
    private long timeOffset;

    public Daytime() {
        timeZone = TimeZone.getTimeZone("UTC");
        now();
    }

    public Daytime(TimeZone timeZone) {
        this.timeZone = timeZone;
        now();
    }

    public void now() {
        long now = System.currentTimeMillis() + timeOffset;
        if (now == lastMillis) return;
        long cachePeriod = now/HOUR_MS;
        // could the day have changed?
        if (cachePeriod != lastMillis/HOUR_MS) {
            timeOffset = timeZone.getOffset(now);
            Calendar cal = Calendar.getInstance(timeZone);
            year = (short) cal.get(Calendar.YEAR);
            month = (byte) cal.get(Calendar.MONTH);
            day = (byte) cal.get(Calendar.DAY_OF_MONTH);
            hour = (byte) cal.get(Calendar.HOUR);
        }
        millis = (short) (now % 1000);
        now /= 1000;
        sec = (byte) (now % 60);
        now /= 60;
        min = (byte) (now % 60);
    }

    public static void main(String... args) {
        Daytime dt = new Daytime();
        long start = System.nanoTime();
        final int runs = 10 * 1000 * 1000;
        for(int i=0;i< runs;i++)
            dt.now();
        long time = System.nanoTime() - start;
        System.out.printf("Daytime.now() took %.3f micro-seconds on average%n", time/1e3/runs);
    }
}

打印

Daytime.now() took 0.287 micro-seconds on average

关于夏令时更改如何发生有多种假设。您可能需要更改检查周期以满足您的需要。

You can get the current time and calculate the current hours,min,second,millis by division and remainder. The day,month,years only change once per day so you only need to calculate that when it changes.

You can use the cached day/month/year and calculate the rest in sub-micro-second time, without creating objects (more than once per day)

import java.util.Calendar;
import java.util.TimeZone;

public class Daytime {
    private static final long HOUR_MS = 3600*1000;

    public short year;
    public byte month, day;
    public byte hour, min, sec;
    public short millis;

    private long lastMillis = Integer.MIN_VALUE;
    private final TimeZone timeZone;
    private long timeOffset;

    public Daytime() {
        timeZone = TimeZone.getTimeZone("UTC");
        now();
    }

    public Daytime(TimeZone timeZone) {
        this.timeZone = timeZone;
        now();
    }

    public void now() {
        long now = System.currentTimeMillis() + timeOffset;
        if (now == lastMillis) return;
        long cachePeriod = now/HOUR_MS;
        // could the day have changed?
        if (cachePeriod != lastMillis/HOUR_MS) {
            timeOffset = timeZone.getOffset(now);
            Calendar cal = Calendar.getInstance(timeZone);
            year = (short) cal.get(Calendar.YEAR);
            month = (byte) cal.get(Calendar.MONTH);
            day = (byte) cal.get(Calendar.DAY_OF_MONTH);
            hour = (byte) cal.get(Calendar.HOUR);
        }
        millis = (short) (now % 1000);
        now /= 1000;
        sec = (byte) (now % 60);
        now /= 60;
        min = (byte) (now % 60);
    }

    public static void main(String... args) {
        Daytime dt = new Daytime();
        long start = System.nanoTime();
        final int runs = 10 * 1000 * 1000;
        for(int i=0;i< runs;i++)
            dt.now();
        long time = System.nanoTime() - start;
        System.out.printf("Daytime.now() took %.3f micro-seconds on average%n", time/1e3/runs);
    }
}

prints

Daytime.now() took 0.287 micro-seconds on average

There are various assumptions about how daylight saving changes occur. You may need to have the checking period change to suit you needs.

多像笑话 2024-11-24 03:09:41

仅使用一个对象并更新它的时间,如下所示:

Date d = new Date();
...
d.setTime(System.currentTimeMillis());

Use only one object and update it's time like so:

Date d = new Date();
...
d.setTime(System.currentTimeMillis());
深海不蓝 2024-11-24 03:09:41

您可以使用 java.util.Calander,如果对此不满意,您可以使用 Joda Time

这可以帮助你。

You can use java.util.Calander, and if not happy with that you can probable use Joda Time.

This can help you out.

等风也等你 2024-11-24 03:09:41

您可以使用 Joda Time 因为它比日历快得多,并且执行以下操作:

LocalDateTime now = new LocalDateTime(); // automatically points to current datetime.
int hour = now.getHourOfDay();
int day = now.getDayOfMonth();
int week = now.getWeekOfWeekyear();
int month = now.getMonthOfYear();
int year = now.getYear();
int season = getSeason(day, month);

getSeason() 很简单来实施。没有任何解决方案可以在不创建任何对象的情况下完成所有这一切。顺便问一下,为什么需要这么多性能?!?!

You may use Joda Time because it's much faster than Calendar, and do this:

LocalDateTime now = new LocalDateTime(); // automatically points to current datetime.
int hour = now.getHourOfDay();
int day = now.getDayOfMonth();
int week = now.getWeekOfWeekyear();
int month = now.getMonthOfYear();
int year = now.getYear();
int season = getSeason(day, month);

The getSeason() is easy to implement. There is no solution that does all this without creating any object. By the way, why do you need so much performance?!?!

墨洒年华 2024-11-24 03:09:41

Be aware that Calendar.getInstance is quite expensive, but you can typically get your Calendar object by invoking that method once and reusing (unless you need Calendar per thread: Calendar is not thread safe).

铜锣湾横着走 2024-11-24 03:09:41

我在 SO 上读了很多关于 Joda Time 的帖子,现在我终于下载了它并尝试了一下。

加雷斯·戴维斯的答案已经被接受,我对此没有异议。但我很想知道乔达时间在哪里发挥了作用。

根据问题和接受的答案,我制作了一个类来比较 JDK Calendar 和 Joda Time Chronology 的执行时间。

我发现日历实现的运行速度始终更快,而不是快两倍。

import java.util.Calendar;
import java.util.Date;

import org.joda.time.Chronology;
import org.joda.time.chrono.ISOChronology;


public class CalendarTest {

    private static final int ITERATIONS = 1000000;

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            jdkCalendar();
            jodaChronology();
        }
    }

    private static void jdkCalendar() {
        long start = System.currentTimeMillis();
        Calendar c = Calendar.getInstance();
        int hourOfDay = 0;
        int dayOfMonth = 0;
        int weekOfYear = 0;
        int month = 0;
        int year = 0;
        for (int i = 0; i < ITERATIONS; i++) {
            c.setTimeInMillis(System.currentTimeMillis());
            hourOfDay = c.get(Calendar.HOUR_OF_DAY);
            dayOfMonth = c.get(Calendar.DAY_OF_MONTH);
            weekOfYear = c.get(Calendar.WEEK_OF_YEAR);
            month = c.get(Calendar.MONTH);
            year = c.get(Calendar.YEAR);
        }
        long duration = System.currentTimeMillis() - start;
        System.err.printf("jdk:  duration %d, hourOfDay: %d, dayOfMonth: %d, weekOfYear: %d, month: %d, year: %d\n", duration, hourOfDay, dayOfMonth, weekOfYear, month, year);
    }

    private static void jodaChronology() {
        long start = System.currentTimeMillis();
        Chronology chronology = ISOChronology.getInstanceUTC(); // This can be static
        int hourOfDay = 0;
        int dayOfMonth = 0;
        int weekOfYear = 0;
        int month = 0;
        int year = 0;
        for (int i = 0; i < ITERATIONS; i++) {
            long msSinceEpoch = System.currentTimeMillis();
            hourOfDay = chronology.hourOfDay().get(msSinceEpoch);
            dayOfMonth = chronology.dayOfMonth().get(msSinceEpoch);
            weekOfYear = chronology.weekOfWeekyear().get(msSinceEpoch);
            month = chronology.monthOfYear().get(msSinceEpoch);
            year = chronology.years().getValue(msSinceEpoch);
        }
        long duration = System.currentTimeMillis() - start;
        System.err.printf("joda: duration %d, hourOfDay: %d, dayOfMonth: %d, weekOfYear: %d, month: %d, year: %d\n", duration, hourOfDay, dayOfMonth, weekOfYear, month, year);
    }

}

示例输出:

jdk:  duration 1714, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 2099, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 377, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 689, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 340, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 680, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 330, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 653, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 326, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 596, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 337, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 620, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 471, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 590, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 326, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 591, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 336, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 595, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 327, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 560, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41

I have read so many posts about Joda Time on SO now that I finally downloaded it and gave it a try.

The answer from Gareth Davis has already been accepted, and I have no issue with that. But I am curious to know where it is that Joda Time made the difference.

Based on the question and the accepted answer, I made a class to compare the execution times of JDK Calendar and Joda Time Chronology.

I find that the Calendar implementation runs consistently faster, not quite twice as fast.

import java.util.Calendar;
import java.util.Date;

import org.joda.time.Chronology;
import org.joda.time.chrono.ISOChronology;


public class CalendarTest {

    private static final int ITERATIONS = 1000000;

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            jdkCalendar();
            jodaChronology();
        }
    }

    private static void jdkCalendar() {
        long start = System.currentTimeMillis();
        Calendar c = Calendar.getInstance();
        int hourOfDay = 0;
        int dayOfMonth = 0;
        int weekOfYear = 0;
        int month = 0;
        int year = 0;
        for (int i = 0; i < ITERATIONS; i++) {
            c.setTimeInMillis(System.currentTimeMillis());
            hourOfDay = c.get(Calendar.HOUR_OF_DAY);
            dayOfMonth = c.get(Calendar.DAY_OF_MONTH);
            weekOfYear = c.get(Calendar.WEEK_OF_YEAR);
            month = c.get(Calendar.MONTH);
            year = c.get(Calendar.YEAR);
        }
        long duration = System.currentTimeMillis() - start;
        System.err.printf("jdk:  duration %d, hourOfDay: %d, dayOfMonth: %d, weekOfYear: %d, month: %d, year: %d\n", duration, hourOfDay, dayOfMonth, weekOfYear, month, year);
    }

    private static void jodaChronology() {
        long start = System.currentTimeMillis();
        Chronology chronology = ISOChronology.getInstanceUTC(); // This can be static
        int hourOfDay = 0;
        int dayOfMonth = 0;
        int weekOfYear = 0;
        int month = 0;
        int year = 0;
        for (int i = 0; i < ITERATIONS; i++) {
            long msSinceEpoch = System.currentTimeMillis();
            hourOfDay = chronology.hourOfDay().get(msSinceEpoch);
            dayOfMonth = chronology.dayOfMonth().get(msSinceEpoch);
            weekOfYear = chronology.weekOfWeekyear().get(msSinceEpoch);
            month = chronology.monthOfYear().get(msSinceEpoch);
            year = chronology.years().getValue(msSinceEpoch);
        }
        long duration = System.currentTimeMillis() - start;
        System.err.printf("joda: duration %d, hourOfDay: %d, dayOfMonth: %d, weekOfYear: %d, month: %d, year: %d\n", duration, hourOfDay, dayOfMonth, weekOfYear, month, year);
    }

}

Sample output:

jdk:  duration 1714, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 2099, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 377, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 689, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 340, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 680, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 330, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 653, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 326, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 596, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 337, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 620, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 471, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 590, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 326, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 591, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 336, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 595, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
jdk:  duration 327, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 5, year: 2011
joda: duration 560, hourOfDay: 12, dayOfMonth: 24, weekOfYear: 25, month: 6, year: 41
好倦 2024-11-24 03:09:41

当您每次需要在调用字段的 getter 之前创建 DateTime 类的实例时,我会推荐 JodaTime。但是,当您调用 getters 方法多于创建实例时,最好使用 JDK 8 中的 java.time 库,或向后移植 ThreeTenABP

这是因为 JodaTime 的 DateTime 类仅存储自纪元开始以来的 long iMillis ,并且某些字段(例如 分钟OfHour、dayOfMonth)的所有 getter 总是从头开始计算该值。但是 java.time 的 ZonedDateTime 将此字段存储在单独的变量中,例如:intyear、shortmonth、shortday,...
我创建了 一些比较基准

I would recomend JodaTime when you need to create an instance of DateTime class every time before calling getters of fields. But when you call getters methods more than create instances it is better to use java.time library from JDK 8, or backport ThreeTenABP.

It is because DateTime class of JodaTime stores only a long iMillis since the start of the epoch and all getters of certain fields like minuteOfHour, dayOfMonth, always calculates this values from scratch. But ZonedDateTime of java.time stores this fields in separate variables like: int year, short month, short day,...
I have created some benchmarks for comparision

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文