@@ -35,21 +35,53 @@ static void writeTimestamp(Writer writer, long timestampMs) throws IOException {
3535 }
3636
3737 static void writeEscapedLabelValue (Writer writer , String s ) throws IOException {
38- for (int i = 0 ; i < s .length (); i ++) {
39- char c = s .charAt (i );
38+ // optimize for the common case where no escaping is needed
39+ int start = 0 ;
40+ // #indexOf is a vectorized intrinsic
41+ int backslashIndex = s .indexOf ('\\' , start );
42+ int quoteIndex = s .indexOf ('\"' , start );
43+ int newlineIndex = s .indexOf ('\n' , start );
44+
45+ int allEscapesIndex = backslashIndex & quoteIndex & newlineIndex ;
46+ while (allEscapesIndex != -1 ) {
47+ int escapeStart = Integer .MAX_VALUE ;
48+ if (backslashIndex != -1 ) {
49+ escapeStart = backslashIndex ;
50+ }
51+ if (quoteIndex != -1 ) {
52+ escapeStart = Math .min (escapeStart , quoteIndex );
53+ }
54+ if (newlineIndex != -1 ) {
55+ escapeStart = Math .min (escapeStart , newlineIndex );
56+ }
57+
58+ // bulk write up to the first character that needs to be escaped
59+ if (escapeStart > start ) {
60+ writer .write (s , start , escapeStart - start );
61+ }
62+ char c = s .charAt (escapeStart );
63+ start = escapeStart + 1 ;
4064 switch (c ) {
4165 case '\\' :
42- writer .append ("\\ \\ " );
66+ writer .write ("\\ \\ " );
67+ backslashIndex = s .indexOf ('\\' , start );
4368 break ;
4469 case '\"' :
45- writer .append ("\\ \" " );
70+ writer .write ("\\ \" " );
71+ quoteIndex = s .indexOf ('\"' , start );
4672 break ;
4773 case '\n' :
48- writer .append ("\\ n" );
74+ writer .write ("\\ n" );
75+ newlineIndex = s .indexOf ('\n' , start );
4976 break ;
50- default :
51- writer .append (c );
5277 }
78+
79+ allEscapesIndex = backslashIndex & quoteIndex & newlineIndex ;
80+ }
81+ // up until the end nothing needs to be escaped anymore
82+ int remaining = s .length () - start ;
83+ if (remaining > 0 ) {
84+ writer .write (s , start , remaining );
5385 }
5486 }
5587
0 commit comments