Skip to content

Commit 1dba087

Browse files
committed
Return fragment results as children arrays, skip the intermediate node
Multi-branch fragment rules can't be expanded at grammar build time, but their runtime role is still trivial: match a sequence of symbols and have the caller splice the resulting children into its own node. The old code allocated a full WP_Parser_Node for each fragment match just to have the caller immediately copy its children out. Return the children array directly from fragments instead. The caller distinguishes via is_array($subnode) and splices in-place, saving a Parser_Node allocation per fragment match (~253k per 10k queries). End-to-end parser benchmark: Before: ~27,000 QPS (avg) After: ~28,700 QPS (+6%).
1 parent 6c9b869 commit 1dba087

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

packages/mysql-on-sqlite/src/parser/class-wp-parser.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ private function parse_recursive( $rule_id ) {
7272
$branches = $this->rules[ $rule_id ];
7373
$fragment_ids = $this->fragment_ids;
7474
$rule_name = $this->rule_names[ $rule_id ];
75+
$is_fragment = isset( $fragment_ids[ $rule_id ] );
7576
$is_select_statement = 'selectStatement' === $rule_name;
7677
$branch_matches = false;
7778
$children = array();
@@ -102,8 +103,11 @@ private function parse_recursive( $rule_id ) {
102103
if ( true === $subnode ) {
103104
continue;
104105
}
105-
if ( isset( $fragment_ids[ $subrule_id ] ) ) {
106-
foreach ( $subnode->get_children_ref() as $c ) {
106+
if ( is_array( $subnode ) ) {
107+
// Fragment results are returned directly as a children
108+
// array so the parser does not allocate a Parser_Node
109+
// that would immediately be unwrapped into the parent.
110+
foreach ( $subnode as $c ) {
107111
$children[] = $c;
108112
}
109113
} else {
@@ -141,6 +145,14 @@ private function parse_recursive( $rule_id ) {
141145
return true;
142146
}
143147

148+
// Fragments exist only to group symbols for reuse; their "node" would
149+
// get inlined into the parent on the very next step. Return the raw
150+
// children array so the caller can splice it without allocating a
151+
// throwaway WP_Parser_Node.
152+
if ( $is_fragment ) {
153+
return $children;
154+
}
155+
144156
return new WP_Parser_Node( $rule_id, $rule_name, $children );
145157
}
146158
}

0 commit comments

Comments
 (0)