Once #3935 is resolved, we might end up with no VisitListeners in the AbstractContext type, if clients aren't using any visit listeners. This means that we don't need to create any related instances of ArrayDeque in the AbstractContext:
// [#2665] VisitListener API
final VisitListener[] visitListeners;
private final Deque<Clause> visitClauses; // Unneeded, if visitListeners.length == 0
private final DefaultVisitContext visitContext; // Unneeded, if visitListeners.length == 0
private final Deque<QueryPart> visitParts; // Unneeded, if visitListeners.length == 0
Neither do we need to push and pop QueryParts onto these stacks. Avoiding to do so will decrease the pressure on GC, as well as speed up AST traversal in general. In a benchmark run against H2, this accounts for an improvement of 20%!
This is a finding from analyses made after a third-party benchmark comparing jOOQ with JDBC, Hibernate, Spring Data:
https://github.com/nithril/sandbox-query-benchmark-jooq-hibernate-jdbc