From 01b0a06239f7f2d0ffebbcfb30ad30129f511332 Mon Sep 17 00:00:00 2001 From: Arnaud Gourlay Date: Fri, 17 Jul 2026 11:47:29 +0200 Subject: [PATCH] Skip loggable operation copy when slow-request collector is off remove_details deep-copies every update operation (per named vector: a String clone, a small Vec alloc, and a SipHash insert into a fresh HashMap) before the update runs, only to feed the slow-request collector. When the collector was never initialized this work is pure overhead on every update; it showed up as a top CPU consumer in model_testing profiles. Build the loggable copy only when the collector is initialized. Co-Authored-By: Claude Fable 5 --- lib/collection/src/profiling/interface.rs | 7 +++++++ .../src/update_workers/update_worker.rs | 15 ++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/collection/src/profiling/interface.rs b/lib/collection/src/profiling/interface.rs index 288331fa55..63bb6ba497 100644 --- a/lib/collection/src/profiling/interface.rs +++ b/lib/collection/src/profiling/interface.rs @@ -8,6 +8,13 @@ use crate::profiling::slow_requests_log::LogEntry; static REQUESTS_COLLECTOR: OnceCell = OnceCell::const_new(); +/// Whether the requests profile collector has been initialized. +/// +/// Allows callers to skip building loggable copies of requests when profiling is disabled. +pub fn is_requests_profile_collector_initialized() -> bool { + REQUESTS_COLLECTOR.get().is_some() +} + /// This function should be used to log request profiles into the shared log structure. /// This structure is later can be read via API. pub fn log_request_to_collector( diff --git a/lib/collection/src/update_workers/update_worker.rs b/lib/collection/src/update_workers/update_worker.rs index cace3b466b..b9048b5d3a 100644 --- a/lib/collection/src/update_workers/update_worker.rs +++ b/lib/collection/src/update_workers/update_worker.rs @@ -13,7 +13,9 @@ use tokio_util::task::AbortOnDropHandle; use crate::collection_manager::collection_updater::CollectionUpdater; use crate::operations::generalizer::Generalizer; use crate::operations::types::{CollectionError, CollectionResult, UpdateStatus}; -use crate::profiling::interface::log_request_to_collector; +use crate::profiling::interface::{ + is_requests_profile_collector_initialized, log_request_to_collector, +}; use crate::shards::CollectionId; use crate::shards::update_tracker::UpdateTracker; use crate::update_handler::{OperationData, OptimizerSignal, UpdateSignal}; @@ -326,7 +328,8 @@ impl UpdateWorkers { // This represents the operation without vectors and payloads for logging purposes // Do not use for anything else - let loggable_operation = operation.remove_details(); + let loggable_operation = + is_requests_profile_collector_initialized().then(|| operation.remove_details()); let cpu_utilization = hw_measurements.cpu_utilization(); @@ -349,9 +352,11 @@ impl UpdateWorkers { None }; - log_request_to_collector(&collection_name, duration, cpu_usage_ratio, move || { - loggable_operation - }); + if let Some(loggable_operation) = loggable_operation { + log_request_to_collector(&collection_name, duration, cpu_usage_ratio, move || { + loggable_operation + }); + } result }