在我看来,在这两种方法中,第一种方法具有与string concat
和toCharArray
相关的性能问题。但有人告诉我,这两个操作都是在编译时发生的,所以没有性能开销。
如果这是真的那么为什么编译时操作不是性能开销?
private final static char[] DigitTens = {
("0000000000"+ "1111111111"+"2222222222"+"3333333333"+"4444444444" //
+"5555555555"+"6666666666"+"7777777777"+"8888888888"+"9999999999")
.toCharArray();
};
VS
private final static char[] DigitTens = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
'3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
'4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
'5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
'6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
'7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
'8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
'9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
};
答案 0 :(得分:3)
带有+
的字符串连接表达式是constant expression,并在编译时解析(JLS§15.28)。但是,toCharArray()
调用在运行时执行。总的来说,您的第一个代码段相当于:
private final static char[] DigitTens;
static {
DigitTens = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
.toCharArray();
}
你的第二个片段相当于:
private final static char[] DigitTens;
static {
DigitTens = new char[100];
DigitTens[0] = '0';
DigitTens[1] = '0';
...
DigitTens[99] = '9';
}
(您可以通过javap -c
)
最后,不要担心这里的表现;你可能不会看到差异。选择您认为更清晰,更易于管理的内容。编译代码所需的时间通常是无关紧要的,因为编译阶段实际上应该只发生一次,之后你将处理包含字节码的生成的.class
文件。
我还要指出,在这种特定情况下,DigitTens[i]
只是i / 10
,假设i
在0-99范围内,包括在内。
答案 1 :(得分:1)
回答这个问题
如果这是真的那么为什么编译时操作不是性能 间接费用?
他们是。但它们只在每个程序创建时出现一次,而且从不在程序运行期间出现。
我认为我不必担心编译器性能(除了查看构建的整体结构)。我会编写清晰的代码而不用担心性能,除非它成为一个问题。这同样适用于运行时性能。
答案 2 :(得分:0)
“编译时”的性能开销会影响开发人员,并可能使他/她在整个生命中花费一毫秒。
运行时性能开销可能每秒发生x次,成本会更高。
至于你的具体例子,第二种方法效率稍高(可以说是以清晰为代价),因为它消除了在运行时调用toCharArray的需要。