用Java解析YYYYMMdd日期的最快方法

时间:2012-04-04 15:10:53

标签: java parsing date date-parsing

解析YYYYMMdd日期时,例如2012年4月5日20120405,最快的方法是什么?

int year = Integer.parseInt(dateString.substring(0, 4));
int month = Integer.parseInt(dateString.substring(4, 6));
int day = Integer.parseInt(dateString.substring(6));

VS

int date = Integer.parseInt(dateString)
year = date / 10000;
month = (date % 10000) / 100; 
day = date % 100;

月份的模10000将是因为mod 10000导致MMdd而结果/ 100是MM

在第一个例子中,我们做3个String操作,3个“解析到int”,在第二个例子中,我们通过modulo做很多事情。

什么更快?有更快的方法吗?

6 个答案:

答案 0 :(得分:33)

SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
Date date = format.parse("20120405");

答案 1 :(得分:14)

如下所示,只有当您查看百万次迭代时,日期处理的性能才有意义。相反,您应该选择易于阅读和维护的解决方案。

虽然你可以使用SimpleDateFormat,但它不是可重入的,所以应该避免使用。最好的解决方案是使用伟大的Joda时间类:

private static final DateTimeFormatter DATE_FORMATTER = new DateTimeFormatterBuilder()
     .appendYear(4,4).appendMonthOfYear(2).appendDayOfMonth(2).toFormatter();
...
Date date = DATE_FORMATTER.parseDateTime(dateOfBirth).toDate();

如果我们谈论你的数学函数,首先要指出的是你的数学代码中存在我修复过的错误。 这是手工操作的问题。也就是说,处理字符串一次的将是最快的。快速测试表明:

year = Integer.parseInt(dateString.substring(0, 4));
month = Integer.parseInt(dateString.substring(4, 6));
day = Integer.parseInt(dateString.substring(6));

需要约800毫秒时间:

int date = Integer.parseInt(dateString);
year = date / 10000;
month = (date % 10000) / 100; 
day = date % 100;
total += year + month + day;

需要大约400毫秒。

然而......再次...... 您需要考虑这是在 1000万次次迭代之后。这是过早优化的完美示例。我会选择最易读且最容易维护的那个。这就是为什么Joda的时间回答是最好的。

答案 2 :(得分:5)

我做了一个快速基准测试,其中两种方法各执行了100万次。 结果清楚地表明模数方法更快,正如Dilum Ranatunga预测的那样。

t.startTiming();
for(int i=0;i<1000000;i++) {
    int year = Integer.parseInt(dateString.substring(0, 4));
    int month = Integer.parseInt(dateString.substring(4, 6));
    int day = Integer.parseInt(dateString.substring(6));
}
t.stopTiming();
System.out.println("First method: "+t.getElapsedTime());

Time t2 = new Time();
t2.startTiming();
for(int i=0;i<1000000;i++) {
    int date = Integer.parseInt(dateString);
    int y2 = date / 1000;
    int m2 = (date % 1000) / 100;
    int d2 = date % 10000;
}
t2.stopTiming();
System.out.println("Second method: "+t2.getElapsedTime());

结果不在于(以毫秒为单位)。

First method: 129
Second method: 53

答案 3 :(得分:3)

第二个肯定会更快,一旦您将mod更改为%并添加缺少的分号并在year计算中修复除数。也就是说,我发现很难想象这是一个瓶颈的应用程序。您有多少次将YYYYMMdd日期解析为其组件,而无需验证它们?

答案 4 :(得分:3)

怎么样(但它会解析一个无效的日期而不说任何话......):

public static void main(String[] args) throws Exception {
    char zero = '0';
    int yearZero = zero * 1111;
    int monthAndDayZero = zero * 11;
    String s = "20120405";
    int year = s.charAt(0) * 1000 + s.charAt(1) * 100 + s.charAt(2) * 10 + s.charAt(3) - yearZero;
    int month = s.charAt(4) * 10 + s.charAt(5) - monthAndDayZero;
    int day = s.charAt(6) * 10 + s.charAt(7) - monthAndDayZero;
}

执行快速而肮脏的基准测试,100,000次迭代预热和10,000,000次定时迭代,我得到:

  • 700ms为您的第一种方法
  • 你的第二种方法350毫秒
  • 用我的方法10ms。

答案 5 :(得分:0)

我相信mod方法会更快。通过调用函数在堆栈上创建变量和位置实例,并创建更重的解决方案。

Mod是标准数学运算符,很可能是非常优化的。

但正如Hunter McMillen所说:“你应该看一下Calendar类API”