Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Java解析YYYYMMdd日期的最快方法_Java_Parsing_Date_Date Parsing - Fatal编程技术网

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

用Java解析YYYYMMdd日期的最快方法,java,parsing,date,date-parsing,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 月的mod 10000是因为mod 10000的结果是MMdd,而/

分析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

月的mod 10000是因为mod 10000的结果是MMdd,而/100的结果是MM

在第一个例子中,我们做了3个字符串操作和3个“解析为int”,在第二个例子中,我们通过模做了很多事情


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

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

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

Mod是标准的数学运算符,很可能是经过优化的

但正如Hunter McMillen所说,“您应该看看Calendar类API”

如何(但它会解析无效的日期而不说任何内容……):

通过100000次迭代热身和10000000次定时迭代,快速完成一个肮脏的基准测试,我得到:

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

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

尽管可以使用
SimpleDateFormat
,但它不可重入,因此应该避免使用。最好的解决方案是使用伟大的Joda time类:

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 time的答案是最好的

我做了一个快速基准测试,两种方法都执行了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());


我可以想象,模运算比分配三个(子)字符串快得多……为什么你不能编写自己的微基准测试,看看哪一个更快?@DilumRanatunga我相信有办法获取共享底层数组的子字符串。许多语言不这样做(至少在默认情况下不是这样),因为它可能导致泄漏,但它非常适合这样的用例。为什么不自己测量一下呢?Dillum,在Java中创建子字符串是O(1)(至少在Sun的实现中)并且不涉及复制。但最好使用实际的日期解析器来完成。无论哪种情况下,代码都不会出现性能问题(至少不太可能)。+1正确的方法是这样做的。这是一种方法,解析日期字符串应该需要性能优化,除非您确定在每个请求的循环中这样做的次数超过1000万次或类似的情况。。。(在这种情况下,您应该想知道为什么)。这是一个了解您的工具的经典示例。Java date API通常太慢了。@user3001出于好奇,您什么时候发现它太慢了?这不是设计最好的API(轻描淡写),但我已经使用了多年,没有出现性能问题。@nim不确定你的意思-计算后的年份是2012年。忽略我的评论,我没有看到调整
yearZero
等。在几乎所有正常情况下,我更喜欢OP发布的模解决方案,即使这更快。为什么?因为当您看到代码时,几秒钟内就掌握了正在发生的事情。您的代码稍微聪明一点,但也需要更多的时间来理解,这是一个缺点。我怀疑在很多情况下,日期转换是性能瓶颈。@Alderath完全同意-我永远不会在代码中包含我发布的内容!但它确实回答了这个问题+1-指出OP可能在浪费时间寻找最快的解决方案。+1-指出OP方法中的缺陷。我只是希望OP能理解……我知道这是老问题,但我纠正了这个问题以避免混淆。
year = Integer.parseInt(dateString.substring(0, 4));
month = Integer.parseInt(dateString.substring(4, 6));
day = Integer.parseInt(dateString.substring(6));
int date = Integer.parseInt(dateString);
year = date / 10000;
month = (date % 10000) / 100; 
day = date % 100;
total += year + month + day;
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