> PS By coincidence, Aleksey is a colleague at Google, working on BigQuery 
> performance.

Oops. I was thinking of a different Alexey. I see that Aleksey
Shipilëv is at AWS.

Julian

On Thu, Jul 11, 2024 at 7:43 AM Julian Hyde <jhyde.apa...@gmail.com> wrote:
>
> Thanks for the article, Stamatis. I learned a lot.
>
> I believe that upgrading to JavaCC 7.0.5 (or higher) will solve the first 
> problem in Aleksey‘s article (stack trace construction) but not the second 
> (stack trace unwinding).
>
> JavaCC uses exceptions extensively in its lookahead logic. (There hundreds of 
> ‘catch (LookaheadSuccess)’ blocks in our code, and I would guess that we 
> invoke lookahead once per line in a typical query, but the number of frames 
> to be unwound each lookahead is very small.) I have to hope that the JavaCC 
> team have evaluated the performance implications.
>
> Julian
>
> PS By coincidence, Aleksey is a colleague at Google, working on BigQuery 
> performance.
>
> > On Jul 11, 2024, at 05:48, Stamatis Zampetakis <zabe...@gmail.com> wrote:
> >
> > This reminds me of a very nice benchmark done by Aleksey Shipilёv
> > around the performance implications of Exception [1]. Among other
> > things the benchmark analyses the impact of stack depth in the
> > performance of exceptions and is very similar to the parser benchmark
> > contributed by Cyril.
> >
> > The closing meme says everything: "If you didn't want exceptions to
> > ruin your performance you shouldn't have used them for the regular
> > control flow"
> >
> > Best,
> > Stamatis
> >
> > [1] https://shipilev.net/blog/2014/exceptional-performance/
> >
> >> On Thu, Jul 11, 2024 at 10:12 AM Cyril DE CATHEU
> >> <cy...@startree.ai.invalid> wrote:
> >>
> >> https://github.com/apache/calcite/pull/3853
> >>
> >>> On Wed, Jul 10, 2024 at 5:29 PM Julian Hyde <jhyde.apa...@gmail.com> 
> >>> wrote:
> >>>
> >>> PS Your method of increasing stack size by making recursive calls seems
> >>> valid. Your experiments show an improvement before and after the fix.
> >>> That’s good enough for me.
> >>>
> >>> I plan to use your benchmark to check that upgrading JavaCC doesn’t
> >>> introduce other performance problems.
> >>>
> >>> Julian
> >>>
> >>>> On Jul 10, 2024, at 08:18, Julian Hyde <jhyde.apa...@gmail.com> wrote:
> >>>>
> >>>> A PR with the benchmark would be great. If it is based on jmh I will
> >>> merge it to main, so others can run the benchmark in future, and maybe do
> >>> more performance optimizations on the parser.
> >>>>
> >>>> By the way, it can be on whichever parser variant (core, babel, server)
> >>> is most convenient. I’m pretty sure they have the same performance issues.
> >>>>
> >>>> I’m continuing to work on upgrading JavaCC to 7.0.13, and should have a
> >>> PR ready soon.
> >>>>
> >>>> Julian
> >>>>
> >>>>> On Jul 10, 2024, at 03:54, Cyril DE CATHEU <cy...@startree.ai.invalid>
> >>> wrote:
> >>>>>
> >>>>> Hey Mihai and Julian,
> >>>>>
> >>>>> Thanks for looking at this.
> >>>>> The performance hit depends on the size of the stack.
> >>>>> Here are the numbers I have for the moment: (*not run in a good
> >>> benchmark
> >>>>> setup* but gives an idea)
> >>>>>
> >>>>> Benchmark                                                          Mode
> >>>>> Cnt   Score   Error  Units
> >>>>> BabelParserBenchmark.instantiateBabelParser                        avgt
> >>>>> 7  14.128 ± 0.041  us/op
> >>>>> BabelParserBenchmark.instantiateBabelParserErrorFixed              avgt
> >>>>> 7  12.054 ± 0.039  us/op
> >>>>>
> >>>>> BabelParserBenchmark.instantiateBabelParserBigCallStack            avgt
> >>>>> 7  20.576 ± 0.069  us/op
> >>>>> BabelParserBenchmark.instantiateBabelParserBigCallStackErrorFixed  avgt
> >>>>> 7  12.479 ± 0.068  us/op
> >>>>>
> >>>>> For the smallest error stack possible with JMH, the current version is
> >>> ~15%
> >>>>> slower than with the fix.
> >>>>> With a bigger stack - instantiation that happens on depth ~100 - the
> >>>>> current version gets even slower. With the fix the time is stable.
> >>>>>
> >>>>> Note I'm not sure my method to make the stack bigger is realistic. I
> >>> just
> >>>>> do some recursive calls.
> >>>>> Also to fix the issue I just copied the SqlBabelParserImpl and fixed the
> >>>>> stack trace call, so the results above may not match exactly the change
> >>>>> that will be observed by upgrading to 7.0.13.
> >>>>>
> >>>>> I can create a PR that adds the benchmark (without the hotfix
> >>> *ErrorFixed
> >>>>> one) if it's okay for you.
> >>>>>
> >>>>>>> On Tue, Jul 9, 2024 at 4:07 AM Julian Hyde <jh...@apache.org> wrote:
> >>>>>>
> >>>>>> I've started work on
> >>>>>> https://issues.apache.org/jira/browse/CALCITE-5541, to upgrade to
> >>>>>> 7.0.13. There are still a few errors, but the inefficiency in the
> >>>>>> subclass of Error seems to have been solved.
> >>>>>>
> >>>>>> Can someone work on the microbenchmark? I would like to see numbers
> >>>>>> before and after this fix.
> >>>>>>
> >>>>>> Julian
> >>>>>>
> >>>>>>
> >>>>>>> On Mon, Jul 8, 2024 at 1:51 PM Mihai Budiu <mbu...@gmail.com> wrote:
> >>>>>>>
> >>>>>>> There is an issue to upgrade JavaCC:
> >>>>>> https://issues.apache.org/jira/browse/CALCITE-5541
> >>>>>>>
> >>>>>>> It may be a worthwhile effort to do it.
> >>>>>>>
> >>>>>>> Mihai
> >>>>>>> ________________________________
> >>>>>>> From: Cyril DE CATHEU <cy...@startree.ai.INVALID>
> >>>>>>> Sent: Friday, July 5, 2024 8:55 AM
> >>>>>>> To: dev@calcite.apache.org <dev@calcite.apache.org>
> >>>>>>> Subject: Re: SqlBabelParserImpl instantiation is slow because it
> >>>>>> instantiates a java.lang.Error
> >>>>>>>
> >>>>>>> Me again,
> >>>>>>>
> >>>>>>> So this LookaheadSuccess comes from JavaCC.
> >>>>>>> It seems this issue was solved in JavaCC some time ago, from JavaCC
> >>>>>> 7.0.5:
> >>>>>>> https://github.com/javacc/javacc/pull/99
> >>>>>>>
> >>>>>>
> >>> https://github.com/javacc/javacc/blob/46aa917fda0d0726690e384632e5cefae46bab68/docs/release-notes.md?plain=1#L163
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> On Fri, Jul 5, 2024 at 5:44 PM Cyril DE CATHEU <cy...@startree.ai
> >>>>>> <mailto:cy...@startree.ai>> wrote:
> >>>>>>> Had a deeper look, it seems the LookaheadSuccess instance is exploited
> >>>>>> for conditional branching
> >>>>>>>
> >>>>>>> Eg:
> >>>>>>>
> >>>>>>> try { return !jj_3_2(); }
> >>>>>>> catch(LookaheadSuccess ls) { return true; }
> >>>>>>> finally { jj_save(1, xla); }
> >>>>>>>
> >>>>>>> So I guess lazy instantiation will not help because the
> >>> LookaheadSuccess
> >>>>>> will be instantiated anyway.
> >>>>>>> If we know this error is always caught internally in the class, could
> >>> we
> >>>>>> override the constructor to not do a call to
> >>> Throwable.fillInStackTrace();
> >>>>>> ? which is what makes this slow.
> >>>>>>>
> >>>>>>> On Fri, Jul 5, 2024 at 10:53 AM Cyril DE CATHEU <cy...@startree.ai
> >>>>>> <mailto:cy...@startree.ai>> wrote:
> >>>>>>> Hey,
> >>>>>>>
> >>>>>>> I'm using Calcite to parse snippets of SQL.
> >>>>>>> My (simplified) function looks like this:
> >>>>>>>
> >>>>>>> public static SqlNode expressionToNode(final String sqlExpression,
> >>>>>>>  final SqlParser.Config config) {
> >>>>>>> SqlParser sqlParser = SqlParser.create(sqlExpression, config);
> >>>>>>> try {
> >>>>>>>  return sqlParser.parseExpression();
> >>>>>>> } catch (SqlParseException e) {
> >>>>>>>   //do something
> >>>>>>> }
> >>>>>>> }
> >>>>>>>
> >>>>>>> and it is called many times.
> >>>>>>> The parser set in the config is Babel, so the parser instantiated is
> >>>>>> SqlBabelParserImpl.
> >>>>>>> A SqlBabelParserImpl is instantiated every time this function is
> >>> called.
> >>>>>> From what I understand this parser cannot be re-used easily to parse
> >>>>>> different expressions but let me know if I'm incorrect.
> >>>>>>>
> >>>>>>> The issue I'm encountering is the instantiation of this class is
> >>> pretty
> >>>>>> slow because one of the instance field  jj_ls extends java.lang.Error
> >>> and
> >>>>>> is instantiated when the SqlBabelParserImpl is instantiated.
> >>>>>>>
> >>>>>>> [Screenshot 2024-07-05 at 10.37.17.png]
> >>>>>>>
> >>>>>>> here is the extract of the generated code in SqlBabelParserImpl:
> >>>>>>>
> >>>>>>> static private final class LookaheadSuccess extends java.lang.Error {
> >>> }
> >>>>>>>
> >>>>>>> final private LookaheadSuccess jj_ls = new LookaheadSuccess();
> >>>>>>>
> >>>>>>> final private boolean jj_scan_token(int kind) {
> >>>>>>> if (jj_scanpos == jj_lastpos) {
> >>>>>>>  jj_la--;
> >>>>>>>  if (jj_scanpos.next == null) {
> >>>>>>>    jj_lastpos = jj_scanpos = jj_scanpos.next =
> >>>>>> token_source.getNextToken();
> >>>>>>>  } else {
> >>>>>>>    jj_lastpos = jj_scanpos = jj_scanpos.next;
> >>>>>>>  }
> >>>>>>> } else {
> >>>>>>>  jj_scanpos = jj_scanpos.next;
> >>>>>>> }
> >>>>>>> if (jj_rescan) {
> >>>>>>>  int i = 0; Token tok = token;
> >>>>>>>  while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
> >>>>>>>  if (tok != null) jj_add_error_token(kind, i);
> >>>>>>> }
> >>>>>>> if (jj_scanpos.kind != kind) return true;
> >>>>>>> if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
> >>>>>>> return false;
> >>>>>>> }
> >>>>>>>
> >>>>>>>
> >>>>>>> jj_ls is only used in an error case. (before last line of
> >>> jj_scan_token)
> >>>>>>> I'm assuming the re-use of a single error instance is done on purpose,
> >>>>>>> but could we consider instantiate jj_ls lazily?
> >>>>>>>
> >>>>>>> I can try to do this but I'm a bit lost in the code generation
> >>> codebase
> >>>>>> so I would need some pointers.
> >>>>>>>
> >>>>>>> Have a nice day.
> >>>>>>> --
> >>>>>>>
> >>>>>>> [StarTree] <https://startree.ai>
> >>>>>>> Cyril de Catheu
> >>>>>>> Software Engineer
> >>>>>>> +33 (684) 829-908<tel:+33+(684)+829-908>
> >>>>>>> Follow us: [RSS] <https://www.startree.ai/blogs> [LinkedIn] <
> >>>>>> https://www.linkedin.com/company/startreedata/> [Twitter] <
> >>>>>> https://twitter.com/startreedata> [Slack] <https://stree.ai/slack>
> >>>>>> [YouTube] <https://youtube.com/StarTreeData>
> >>>>>>>
> >>>>>>> [Try StarTree Cloud Today]<
> >>>>>>
> >>> https://get.startree.ai/startree-cloud?utm_campaign=byoc-edition-of-startree-cloud&utm_source=email&utm_content=startree-employee-email-signatures
> >>>>>>>
> >>>>>>
> >>>

Reply via email to