更新:这是 Guava 14 中的 fixed。
您在 u21 和可能的早期版本中遇到了某种 JIT 错误,但至少在一些较新的 JDK 版本中没有。这是 u21 中测试程序的 -XX:+PrintCompilation 输出:
1 java.util.Arrays::binarySearch0 (72 bytes)
2 com.google.common.base.CharMatcher$Or::matches (28 bytes)
3 com.google.common.base.CharMatcher$12::matches (22 bytes)
2 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
4 com.google.common.base.CharMatcher$11::matches (17 bytes)
5 java.util.Arrays::binarySearch (9 bytes)
6 com.google.common.base.CharMatcher$Or::matches (28 bytes)
1% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
6 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
7 com.google.common.base.CharMatcher$Or::matches (28 bytes)
7 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
1% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
2% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
8 com.google.common.base.CharMatcher$Or::matches (28 bytes)
8 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
2% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
3% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
9 com.google.common.base.CharMatcher$Or::matches (28 bytes)
9 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
3% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
4% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
10 com.google.common.base.CharMatcher$Or::matches (28 bytes)
10 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
4% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
11 com.google.common.base.CharMatcher$Or::matches (28 bytes)
5% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
11 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
12 com.google.common.base.CharMatcher$Or::matches (28 bytes)
5% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
12 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
6% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
13 com.google.common.base.CharMatcher$Or::matches (28 bytes)
13 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
6% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
7% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
14 com.google.common.base.CharMatcher$Or::matches (28 bytes)
15 com.google.common.base.CharMatcher::slowGetChars (52 bytes)
14 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
7% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
16 com.google.common.base.CharMatcher$Or::matches (28 bytes)
16 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
17 com.google.common.base.CharMatcher$Or::matches (28 bytes)
17 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
8% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
18 com.google.common.base.CharMatcher$Or::matches (28 bytes)
18 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
19 com.google.common.base.CharMatcher$Or::matches (28 bytes)
19 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
20 com.google.common.base.CharMatcher$Or::matches (28 bytes)
8% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
20 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
21 com.google.common.base.CharMatcher$Or::matches (28 bytes)
21 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
22 com.google.common.base.CharMatcher$Or::matches (28 bytes)
9% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
22 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
23 com.google.common.base.CharMatcher$Or::matches (28 bytes)
23 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
24 com.google.common.base.CharMatcher$Or::matches (28 bytes)
24 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
9% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
25 com.google.common.base.CharMatcher$Or::matches (28 bytes)
25 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
26 com.google.common.base.CharMatcher$Or::matches (28 bytes)
26 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
10% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
27 com.google.common.base.CharMatcher$Or::matches (28 bytes)
27 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
28 com.google.common.base.CharMatcher$Or::matches (28 bytes)
28 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
10% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
29 com.google.common.base.CharMatcher$Or::matches (28 bytes)
29 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
30 com.google.common.base.CharMatcher$Or::matches (28 bytes)
30 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
11% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
31 com.google.common.base.CharMatcher$Or::matches (28 bytes)
31 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
32 com.google.common.base.CharMatcher$Or::matches (28 bytes)
32 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
11% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
33 com.google.common.base.CharMatcher$Or::matches (28 bytes)
33 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
34 com.google.common.base.CharMatcher$Or::matches (28 bytes)
34 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
35 com.google.common.base.CharMatcher$Or::matches (28 bytes)
12% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
35 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
36 com.google.common.base.CharMatcher$Or::matches (28 bytes)
36 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
37 com.google.common.base.CharMatcher$Or::matches (28 bytes)
37 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
12% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
38 com.google.common.base.CharMatcher$Or::matches (28 bytes)
38 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
39 com.google.common.base.CharMatcher$Or::matches (28 bytes)
39 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
13% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
40 com.google.common.base.CharMatcher$Or::matches (28 bytes)
40 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
41 com.google.common.base.CharMatcher$Or::matches (28 bytes)
41 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
13% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
42 com.google.common.base.CharMatcher$Or::matches (28 bytes)
42 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
43 com.google.common.base.CharMatcher$Or::matches (28 bytes)
43 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
44 com.google.common.base.CharMatcher$Or::matches (28 bytes)
14% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
44 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
45 com.google.common.base.CharMatcher$Or::matches (28 bytes)
45 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
46 com.google.common.base.CharMatcher$Or::matches (28 bytes)
46 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
14% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
47 com.google.common.base.CharMatcher$Or::matches (28 bytes)
47 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
48 com.google.common.base.CharMatcher$Or::matches (28 bytes)
48 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
15% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
49 com.google.common.base.CharMatcher$Or::matches (28 bytes)
49 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
50 com.google.common.base.CharMatcher$Or::matches (28 bytes)
50 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
15% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
51 com.google.common.base.CharMatcher$Or::matches (28 bytes)
51 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
52 com.google.common.base.CharMatcher$Or::matches (28 bytes)
52 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
16% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
53 com.google.common.base.CharMatcher$Or::matches (28 bytes)
53 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
54 com.google.common.base.CharMatcher$Or::matches (28 bytes)
54 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
16% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
55 com.google.common.base.CharMatcher$Or::matches (28 bytes)
55 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
56 com.google.common.base.CharMatcher$Or::matches (28 bytes)
56 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
57 com.google.common.base.CharMatcher$Or::matches (28 bytes)
17% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
57 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
58 com.google.common.base.CharMatcher$Or::matches (28 bytes)
58 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
59 com.google.common.base.CharMatcher$Or::matches (28 bytes)
59 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
17% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
60 com.google.common.base.CharMatcher$Or::matches (28 bytes)
60 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
61 com.google.common.base.CharMatcher$Or::matches (28 bytes)
61 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
18% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
62 com.google.common.base.CharMatcher$Or::matches (28 bytes)
62 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
63 com.google.common.base.CharMatcher$Or::matches (28 bytes)
63 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
18% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
64 com.google.common.base.CharMatcher$Or::matches (28 bytes)
64 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
65 com.google.common.base.CharMatcher$Or::matches (28 bytes)
65 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
19% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
66 com.google.common.base.CharMatcher$Or::matches (28 bytes)
<I omitted ~500 very similar lines here>
143% made not entrant com.google.common.base.CharMatcher::setBits @ -2 (30 bytes)
144% com.google.common.base.CharMatcher::setBits @ 2 (30 bytes)
144% made not entrant com.google.common.base.CharMatcher::setBits @ -2 (30 bytes)
145% com.google.common.base.CharMatcher::setBits @ 2 (30 bytes)
145% made not entrant com.google.common.base.CharMatcher::setBits @ -2 (30 bytes)
took 7599 ms
2nd took 0 ms
这是 u34 的相同输出:
64 1 java.util.Arrays::binarySearch0 (72 bytes)
68 2 com.google.common.base.CharMatcher$Or::matches (28 bytes)
68 3 com.google.common.base.CharMatcher$12::matches (22 bytes)
70 4 com.google.common.base.CharMatcher$11::matches (17 bytes)
71 5 java.util.Arrays::binarySearch (9 bytes)
71 1% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
76 2 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
76 6 com.google.common.base.CharMatcher$Or::matches (28 bytes)
88 1% made not entrant com.google.common.base.CharMatcher::slowGetChars @ -2 (52 bytes)
88 6 made not entrant com.google.common.base.CharMatcher$Or::matches (28 bytes)
88 7 com.google.common.base.CharMatcher::slowGetChars (52 bytes)
89 8 com.google.common.base.CharMatcher$Or::matches (28 bytes)
91 9 com.google.common.base.CharMatcher$8::matches (14 bytes)
91 2% com.google.common.base.CharMatcher::slowGetChars @ 9 (52 bytes)
98 10 java.lang.String::indexOf (166 bytes)
98 11 java.lang.String::indexOf (151 bytes)
102 3% com.google.common.base.CharMatcher::setBits @ 2 (30 bytes)
113 12 com.google.common.base.CharMatcher::setBits (30 bytes)
113 13 com.google.common.base.CharMatcher$LookupTable::set (15 bytes)
如您所见,u34 的情况要理智得多。看起来 u21 中发生的事情是 OSR (影响 slowGetChars 方法,因为它有一个大循环)和递归超态调用(影响 CharMatcher$Or 和 CharMatcher 的其他子类 - 被称为在递归CharMatcher$Or链的末尾)产生JIT反优化和后续重新编译的完美风暴,这在u34中得到解决。
不过,我认为 Guava 家伙在静态初始化期间创建 65k 元素 LUT 有点滥用,即使您从不使用有问题的匹配器,当 JIT 正常工作时,这仍然需要大约 50 毫秒。我针对番石榴提交了a bug,让我们看看维护者是否同意:)。 更新:在我提交此问题后的几天内,该错误已得到修复,修复将在 Guava 14 中进行。这就是我所说的快速周转!
原帖如下:
我有完全相同的行为并跑到这篇文章中寻找解决方案。
查看代码,似乎他们正在制作一个 65k 元素(每个元素占用一位)查找表并检查每个字符是否匹配,这需要许多嵌套函数调用,因为 fluent em> 用于定义匹配器的样式:
public static final CharMatcher INVISIBLE = inRange('\u0000', '\u0020')
.or(inRange('\u007f', '\u00a0'))
.or(is('\u00ad'))
.or(inRange('\u0600', '\u0604'))
.or(anyOf("\u06dd\u070f\u1680\u180e"))
.or(inRange('\u2000', '\u200f'))
.or(inRange('\u2028', '\u202f'))
.or(inRange('\u205f', '\u2064'))
.or(inRange('\u206a', '\u206f'))
.or(is('\u3000'))
.or(inRange('\ud800', '\uf8ff'))
.or(anyOf("\ufeff\ufff9\ufffa\ufffb"))
.withToString("CharMatcher.INVISIBLE")
.precomputed();
这是触发长静态初始化的代码,在我的快速盒子上需要大约 7 秒。这是您的应用在我的盒子上的输出:
took 6814 ms
2nd took 0 ms
我正在提交一个番石榴错误。