new SimpleDateFormat("Pattern") 与 applyPattern("Pattern") 的区别和性能优势(如果有的话)?
new SimpleDateFormat("Pattern") vs applyPattern("Pattern") difference and performance benefit if any?
我正在研究 Java 7 中的代码,它使用大量日期转换为字符串和从字符串到日期对象,他们在需要日期时为此创建新的 SimpleDateFormat("Pattern")要转换(总共有 5-6 个模式)。所以我需要问如果我写一些这样的代码会怎样:
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
private SimpleDateFormat getsiSimpleDateFormat(SimpleDateFormat simpleDateFormat, String format){
simpleDateFormat.applyPattern(format);
return simpleDateFormat;
}
所以我在这里重复使用我的 simpleDateFormat 并在必要时添加一个模式。
- 这个方法好吗?
- 或者可以再改进一下?
- 通过使用这种方法,我会面临处理或内存增加的问题吗?
这两个在感觉上是一样的。查看代码,您可以看到使用基本构造函数导致:
public SimpleDateFormat(String pattern)
{
this(pattern, Locale.getDefault(Locale.Category.FORMAT));
}
this
导致:
public SimpleDateFormat(String pattern, Locale locale)
{
if (pattern == null || locale == null) {
throw new NullPointerException();
}
initializeCalendar(locale);
this.pattern = pattern; // This part is important
this.formatData = DateFormatSymbols.getInstanceRef(locale);
this.locale = locale;
initialize(locale);
}
另一方面,使用 applyPattern(pattern)
给出了这个结果:
public void applyPattern(String pattern)
{
compiledPattern = compile(pattern);
this.pattern = pattern; // Same as initialization
}
正如评论中 Roby Cornelissen 所指出的,这两种方法并不完全相同。 applyPattern
假设您已经初始化了 SimpleDateFormat
,但跳过了语言环境 + 日历初始化。
在性能和内存方面,使用 applyPattern
比重新创建对象更好。以前的答案是:
There are, subsequently, only one difference: using applyPattern
will use less memory, as you are using only one object instead of re-initializing a new SimpleDateFormat()
. The choice is up to you.
并且不完全正确(有不止一处不同)。
编辑
如果你想知道,构造函数中的 initialize()
方法会编译模式,因此如果你给它一个错误的模式也会抛出 IllegalArgumentException
。代码(我首先在此处发布)使其看起来不会崩溃。
java.time
SimpleDateFormat
class 是旧的、麻烦的日期时间 classes 的一部分,与不再使用的最早版本的 Java 捆绑在一起。现在是遗留的,它们完全被 java.time classes 所取代。
改用DateTimeFormatter
。
线程安全
遗留日期时间class是而非thread-safe。如果您的应用程序使用线程,或者将来可能使用线程,那么您不应该传递 SimpleDateFormat
的实例以供重用。
相比之下,java.time classes 使用不可变对象并且是线程安全的。您确实可以保留一个 DateTimeFormatter
以供传递和重复使用。
过早的优化
您似乎落入了名为 premature optimization 的陷阱。众所周知,程序员不善于预测其应用程序的性能。预期的瓶颈通常 运行 顺利进行,而其他被忽略的代码会阻塞。现代硬件和操作系统使性能更难预测。
今天的 JVM 实现是高度优化的,可能是历史上优化程度最高的软件。相信他们 运行 你的代码很好。
除了 运行 经常在大循环中避免不必要的实例化和网络连接等一些基础知识外,不必担心性能。而是使用 profiling tools, monitoring tools, and some logging 来确定和 衡量应用的实际性能 以确定合理的性能问题。
我正在研究 Java 7 中的代码,它使用大量日期转换为字符串和从字符串到日期对象,他们在需要日期时为此创建新的 SimpleDateFormat("Pattern")要转换(总共有 5-6 个模式)。所以我需要问如果我写一些这样的代码会怎样:
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
private SimpleDateFormat getsiSimpleDateFormat(SimpleDateFormat simpleDateFormat, String format){
simpleDateFormat.applyPattern(format);
return simpleDateFormat;
}
所以我在这里重复使用我的 simpleDateFormat 并在必要时添加一个模式。
- 这个方法好吗?
- 或者可以再改进一下?
- 通过使用这种方法,我会面临处理或内存增加的问题吗?
这两个在感觉上是一样的。查看代码,您可以看到使用基本构造函数导致:
public SimpleDateFormat(String pattern)
{
this(pattern, Locale.getDefault(Locale.Category.FORMAT));
}
this
导致:
public SimpleDateFormat(String pattern, Locale locale)
{
if (pattern == null || locale == null) {
throw new NullPointerException();
}
initializeCalendar(locale);
this.pattern = pattern; // This part is important
this.formatData = DateFormatSymbols.getInstanceRef(locale);
this.locale = locale;
initialize(locale);
}
另一方面,使用 applyPattern(pattern)
给出了这个结果:
public void applyPattern(String pattern)
{
compiledPattern = compile(pattern);
this.pattern = pattern; // Same as initialization
}
正如评论中 Roby Cornelissen 所指出的,这两种方法并不完全相同。 applyPattern
假设您已经初始化了 SimpleDateFormat
,但跳过了语言环境 + 日历初始化。
在性能和内存方面,使用 applyPattern
比重新创建对象更好。以前的答案是:
There are, subsequently, only one difference: using
applyPattern
will use less memory, as you are using only one object instead of re-initializing anew SimpleDateFormat()
. The choice is up to you.
并且不完全正确(有不止一处不同)。
编辑
如果你想知道,构造函数中的 initialize()
方法会编译模式,因此如果你给它一个错误的模式也会抛出 IllegalArgumentException
。代码(我首先在此处发布)使其看起来不会崩溃。
java.time
SimpleDateFormat
class 是旧的、麻烦的日期时间 classes 的一部分,与不再使用的最早版本的 Java 捆绑在一起。现在是遗留的,它们完全被 java.time classes 所取代。
改用DateTimeFormatter
。
线程安全
遗留日期时间class是而非thread-safe。如果您的应用程序使用线程,或者将来可能使用线程,那么您不应该传递 SimpleDateFormat
的实例以供重用。
相比之下,java.time classes 使用不可变对象并且是线程安全的。您确实可以保留一个 DateTimeFormatter
以供传递和重复使用。
过早的优化
您似乎落入了名为 premature optimization 的陷阱。众所周知,程序员不善于预测其应用程序的性能。预期的瓶颈通常 运行 顺利进行,而其他被忽略的代码会阻塞。现代硬件和操作系统使性能更难预测。
今天的 JVM 实现是高度优化的,可能是历史上优化程度最高的软件。相信他们 运行 你的代码很好。
除了 运行 经常在大循环中避免不必要的实例化和网络连接等一些基础知识外,不必担心性能。而是使用 profiling tools, monitoring tools, and some logging 来确定和 衡量应用的实际性能 以确定合理的性能问题。