[tracker/wip/carlosg/perf-improvements: 1/5] libtracker-data: Avoid revisiting already transacted parser nodes



commit 6e37711eade63ff707a233e4cc9a9998ffa2abe1
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Jun 2 00:32:37 2020 +0200

    libtracker-data: Avoid revisiting already transacted parser nodes
    
    The tracker_parser_state_transact_match() function transacts a
    parser node and all pending parents. But this function visits the
    current parser stack from the root node, even though most often
    most parent nodes will already be present. This is specially
    noticeable with updates as those result in a pretty deep node tree.
    
    This is a significant chunk of first-time indexing in tracker-miner-fs
    according to perf:
    
    8.88%     8.88%  pool-tracker-mi  libtracker-data.so                 [.] 
tracker_parser_state_transact_match
    
    Cache the last transacted rule position and node so we may start
    right from those without visiting the topmost nodes over and over.
    This drops that function to being almost negligible:
    
    0.43%     0.25%  pool-tracker-mi  libtracker-data.so                 [.] 
tracker_parser_state_transact_match

 src/libtracker-data/tracker-sparql-parser.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-parser.c b/src/libtracker-data/tracker-sparql-parser.c
index 0c4ab28e9..83c04734a 100644
--- a/src/libtracker-data/tracker-sparql-parser.c
+++ b/src/libtracker-data/tracker-sparql-parser.c
@@ -67,9 +67,10 @@ struct _TrackerParserState {
                TrackerRuleState *rules;
                guint array_size;
                guint len;
+               gint64 last_matched;
+               TrackerParserNode *last_matched_node;
        } rule_states;
 
-
        GPtrArray *error_rules;
        gssize error_len;
 };
@@ -235,9 +236,16 @@ tracker_parser_state_pop (TrackerParserState *state)
        if (rule_state->node) {
                node = rule_state->node;
                node->end = state->current;
+
+               if (node == state->rule_states.last_matched_node) {
+                       state->rule_states.last_matched_node =
+                               (TrackerParserNode *) node->node.parent;
+               }
        }
 
        state->rule_states.len--;
+       state->rule_states.last_matched = MIN (state->rule_states.last_matched,
+                                              state->rule_states.len);
 
        return node;
 }
@@ -317,13 +325,14 @@ tracker_parser_state_next_child (TrackerParserState *state,
 static TrackerParserNode *
 tracker_parser_state_transact_match (TrackerParserState *state)
 {
-       TrackerParserNode *parser_node = NULL;
-       guint i;
+       TrackerParserNode *parser_node = state->rule_states.last_matched_node;
+       guint i = 0;
 
-       for (i = 0; i < state->rule_states.len; i++) {
+       for (i = state->rule_states.last_matched; i < state->rule_states.len; i++) {
                TrackerRuleState *rule_state = &state->rule_states.rules[i];
 
                rule_state->visited = TRUE;
+               state->rule_states.last_matched = i;
 
                if (rule_state->rule->type != RULE_TYPE_LITERAL &&
                    rule_state->rule->type != RULE_TYPE_TERMINAL &&
@@ -339,6 +348,7 @@ tracker_parser_state_transact_match (TrackerParserState *state)
                }
 
                parser_node = rule_state->node;
+               state->rule_states.last_matched_node = parser_node;
        }
 
        return parser_node;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]