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

在解析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)); 

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

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

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

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

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

虽然您可以使用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的时间答案是最好的。

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

我做了一个快速基准测试,其中两种方法各执行了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 

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

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

 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次定时迭代,我得到:

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

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

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

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