Skip to content

Conversation

@peteruhnak
Copy link
Contributor

This reintroduces closing angle bracket escaping as discussed in #198 .

Note that this applies only to STGroup, not ST -- same way it was in 4.0.4 and prior.

@parrt
Copy link
Member

parrt commented Sep 4, 2020

Hi. Can you sign contributors.txt too?

Comment on lines 161 to 163
String rest = s.substring(i);
if (rest.startsWith("\\>")) {
if (rest.length() == 2 || !rest.substring(2).startsWith(">")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it could have poor performance if s is very long. It's better to do these checks without any substring operations, because they involve copying. You should try using charAt(i+1) and charAt(i+2) instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering the same, because I wrote this in the same style as the previous escapes in the method.

Googling around, it seems that in Java 6 (which is the oldest supported by ST4), String#substring was O(1), but with J7+ it is O(n). I'll make the adjustments for this one. For the rest, it seems you've already addressed it in https://github.com/antlr/stringtemplate4/pull/236/files#diff-4b7cd0c18190068c3a0a57ee6c30a9d4L140-L158 )

@peteruhnak
Copy link
Contributor Author

peteruhnak commented Sep 6, 2020

Hi. Can you sign contributors.txt too?

done

I've realized that the previous \>> case was a subset of the new one so I merged them.

This looks like it could have poor performance if s is very long.

I've also changed the substring to startsWith for all cases.


Out of curiosity I did some basic benchmarks on some files I had:

  • *Substring is the original implementation
  • *StartsWith is the new implementation
  • *Char is experimental implementation that operates on char[] instead of String, but makes it less readable (so imo not worth it unless someone is parsing thousands of massive templates at once)
test name ops/s size in chars ops/s * size
EscapeChangePerf.benchTinySubstring 2,059,220 34 70,013,489
EscapeChangePerf.benchTinyStartsWith 3,154,894 34 107,266,400
EscapeChangePerf.benchTinyChar 10,831,791 34 368,280,883
       
EscapeChangePerf.benchSmallSubstring 75,085 966 72,532,051
EscapeChangePerf.benchSmallStartsWith 128,906 966 124,522,734
EscapeChangePerf.benchSmallChar 455,153 966 439,677,458
       
EscapeChangePerf.benchMediumSubstring 7,465 5,403 40,330,775
EscapeChangePerf.benchMediumStartsWith 24,014 5,403 129,749,603
EscapeChangePerf.benchMediumChar 96,988 5,403 524,023,722
       
EscapeChangePerf.benchLargeSubstring 628 22,556 14,165,145
EscapeChangePerf.benchLargeStartsWith 5,713 22,556 128,858,481
EscapeChangePerf.benchLargeChar 21,201 22,556 478,209,418

Copy link
Contributor

@Clashsoft Clashsoft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@parrt
Copy link
Member

parrt commented Sep 7, 2020

Ok, looks great. Thanks guys.

@parrt parrt merged commit c7a3bb9 into antlr:master Sep 7, 2020
@parrt parrt added this to the 4.3.2 milestone Apr 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants