Sla*_*lam 7 java performance jodatime
有没有快速的方法来创建DateTime实例并将分钟\秒\毫秒设置为0?此时我正在使用以下代码:
private DateTime createDateTime(java.util.Date date, org.joda.time.Chronology chronology) {
DateTime dateTime = new DateTime(date, chronology);
dateTime = dateTime.withMinuteOfHour(0);
dateTime = dateTime.withSecondOfMinute(0);
dateTime = dateTime.withMillisOfSecond(0);
return dateTime;
}
Run Code Online (Sandbox Code Playgroud)
但是当它调用大约200,000次时,dateTime.with***(0); 花了很多时间.可能有更正确的解决方案?
也许是这样的?
// Truncate minutes/seconds/milliseconds from the date's timestamp
long truncatedTimestamp = date.getTime() - date.getTime() % 3600000;
DateTime dateTime = new DateTime(truncatedTimestamp, chronology);
Run Code Online (Sandbox Code Playgroud)
为什么这会更快?
DateTime构造函数中使用快速整数运算(可忽略不计)和1个unix时间戳标准化(昂贵)DateTime构造函数中使用1个unix时间戳标准化(昂贵),并且每次将某个日期部分设置为3时,使用3个标准化(昂贵)0因此,你可能无法击败模数.正如其他人指出的那样,这可能导致在非常偏远的角落情况下不正确的结果,其中小时数不计60秒(例如由于闰秒),虽然我没有看到如何,因为unix时间戳总是可以被截断为零,以获得一个日历时间的开始(欢迎例子).
刚试过下面的代码 - 它看起来像方法1(你的)在我的电脑上需要大约320ms,与方法2(我的)390ms,与方法3(Lukas的)15ms,与方法4(MutableDateTime)310ms ...现在模数可能(?)导致错误的结果.
public class Test {
private static int NUM_RUN;
public static void main(String[] args) {
Date date = new Date();
List<Runnable> list = new ArrayList<>();
list.add(method3Withs(date));
list.add(method1With(date));
list.add(methodModulo(date));
list.add(methodMutable(date));
NUM_RUN = 100_000;
for (Runnable r : list) {
long start = System.nanoTime();
r.run();
long end = System.nanoTime();
System.out.println((end - start) / 1000000);
}
NUM_RUN = 10_000_000;
for (Runnable r : list) {
long start = System.nanoTime();
r.run();
long end = System.nanoTime();
System.out.println((end - start) / 1000000);
}
}
private static Runnable method3Withs(final Date date) {
return new Runnable() {
@Override
public void run() {
DateTime d2 = null;
for (int i = 0; i < NUM_RUN; i++) {
d2 = new DateTime(date);
d2 = d2.withMinuteOfHour(0);
d2 = d2.withSecondOfMinute(0);
d2 = d2.withMillisOfSecond(0);
}
System.out.println(d2);
}
};
}
private static Runnable method1With(final Date date) {
return new Runnable() {
@Override
public void run() {
DateTime d2 = null;
for (int i = 0; i < NUM_RUN; i++) {
d2 = new DateTime(date);
d2 = d2.withTime(d2.getHourOfDay(), 0, 0, 0);
}
System.out.println(d2);
}
};
}
private static Runnable methodModulo(final Date date) {
return new Runnable() {
@Override
public void run() {
DateTime d2 = null;
for (int i = 0; i < NUM_RUN; i++) {
long truncatedTimestamp = date.getTime() - date.getTime() % 3600000;
d2 = new DateTime(truncatedTimestamp);
}
System.out.println(d2);
}
};
}
private static Runnable methodMutable(final Date date) {
return new Runnable() {
@Override
public void run() {
MutableDateTime m = null;
for (int i = 0; i < NUM_RUN; i++) {
m = new MutableDateTime(date);
m.setMinuteOfHour(0);
m.setSecondOfMinute(0);
m.setMillisOfSecond(0);
}
System.out.println(m);
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
我在经历了100,000次热身之后让它达到1000万次:
3037
4068
88
2864
模数方法获得了很大的优势,因此在大多数情况下认为它会表现得更好似乎是安全的.