MASKOR/gologpp

Extremely long parsing time if using a log command

Closed this issue · 5 comments

Before adding a logging command (here log_debug is used, but the exact command doesn't seem to matter) the parsing time of this file was around 45s, which is still bearable. The only change was this single line and now the parsing time is around 10,5 minutes, which is quite annoying.

https://github.com/carologistics/fawkes-robotino-labhlap2019/blob/e7ff7e5c5d54a76c87e706f777660c58f5cd4beb/src/gologpp/rcll/rcll.gpp#L500

Is there an easy way to optimize the code so that the parser can parse it faster?

Thanks, this is a very helpful observation. It confirms my suspicion that one of the most expensive parts of the golog++ grammar is the parsing of reference arguments. That is, everything between the braces ( ... ). In this example, you have a deeply nested expression, which may be causing a complexity that is exponential in the nesting depth. So the workaround would be to un-nest the expression by assigning the individual values to helper fluents and using those as arguments for a less deeply nested expression. Not a very nice solution, but it should reduce the compexity significantly.

@Setcab can you confirm that the workaround helps?

Yes, this seems to help. I introduced some new fluents to have less deeply nested expressions and the parser time got down to 38s. Thank you.

The real problem is that we're using a recursive-descent parser which doesn't know the argument types of a reference expression, so it just tries to parse each argument as each of the predefined types (number, bool, string, symbol, list and compound). And since these can be arbitrarily complex expressions (including nested references, thereby causing recursion) each of those is a pretty big, nondeterministic parser. By changing the parser so that it knows the argument type before it begins to parse it, we should be able to reduce complexity from O(c^6n) to O(c^n), where n is the nesting depth. Somewhat non-trivial to implement, but should be easily testable.

w00tw00t! After 1634c45 we can now parse the original file (i.e. the one that took 10 minutes) in 0.7 seconds. BAM!
Thanks again for the help in narrowing this down :-D