Learning: json.loads, dictionary instantiations (for weights) and global/module-level lookups (like math.log10 or json.loads) inside heavily iterated extraction loops (all_candidates) create significant performance bottlenecks in the codebase.
Action: Extract heavily accessed properties, caching their values via constants (e.g., _PHASE_WEIGHTS) instead of re-instantiating them on every function call. Move json.loads and other global methods to local variables within functions before large loops, and use dict.pop or dict.get iteratively to drastically reduce parsing and lookup latency.
Learning: In the core search engine (QueryService.search), sorted_fids is populated directly from scores.keys(), which in turn comes from all_initial_fids. Since meta_cache is pre-fetched via get_batch_by_fids(all_initial_fids) right before RRF scoring, subsequently calling candidates_meta = self.semantic.meta.get_batch_by_fids(sorted_fids) makes an entirely redundant network/disk round-trip to the SQLite database to fetch data we already have perfectly cached.
Action: When performing complex sorting or scoring over a pre-fetched batch of database items, build subsequent list selections by mapping directly from the original local cache dictionary instead of invoking identical get_batch database queries.
Learning: During the core search operation (QueryService.search), the system was iteratively invoking increment_hit on individual IDs, resulting in multiple synchronous UPDATE queries executing inside a tight loop over all_candidates. This represents an N+1 database I/O bottleneck in an extremely hot path.
Action: Replaced individual hit increments with a single batched UPDATE call (increment_hits_batch) that leverages SQLite's json_each to bypass parameter limits. By aggregating IDs into a list and firing a single query, database overhead and lock contention are significantly minimized.
Learning: In tight loops evaluating dict scores (like trajectory.py recovering paths), using sorted(d.items(), key=lambda x: x[1])[0][0] runs in O(N log N) and creates unnecessary temporary lists. Finding the maximum key directly using max(d, key=d.get) runs in O(N) and operates strictly on the dictionary iterators. Additionally, using lambda functions for key sorting introduces significant Python-level function call overhead.
Action: Always prefer max()/min() over sorting when only the extremes are needed. Replace lambda functions in sorted() or max() with C-optimized accessors like dict.get or operator.itemgetter wherever possible.
Learning: In tight sorting or selection loops, using a Python lambda function inside key= arguments introduces significant function-call overhead.
Action: Replace lambda x: x['key'] with operator.itemgetter('key') and replace lambda p: self.list.index(p) with a direct method reference like self.list.index to leverage C-optimized implementations for measurable performance gains in tight loops.
Learning: In sorting operations over large lists (e.g. events.sort and pending_metas.sort), Python lambda functions combined with dynamic function calls or dict.get methods introduce unnecessary interpreter overhead. Specifically, using inline tuples with a pre-computed dictionary (_priority_map.get) instead of an inline function (get_priority) inside the sort key lambda reduces execution time by over ~50%, while operator.itemgetter completely bypasses Python function call overhead.
Action: Always prefer operator.itemgetter for basic dict access in sort keys, and when mapping categorical priorities, use a predefined constant dictionary map inline rather than calling a local def function inside the lambda.
Learning: Checking for JSON string length before json.loads("{}") prevents throwing heavy exceptions inside tight mapping loops resulting in up to 10-15x iteration parsing speeds. Using inline bounders (if raw_score < 1.0 else 1.0) avoids Python C-API calls that exist using min() resulting in ~2.5x loop performance.
Action: Extract inline checks before triggering expensive parsers (json.loads) inside tight loops to avoid exceptions, and replace global static mapping dictionaries (_PHASE_WEIGHTS.get) with explicit if-elif variable assignments inside hot functions.