Skip to content

perf: Add ScopedProfiler and ProfilerReporter to simplify profiling. #2080

Open
SharafMohamed wants to merge 179 commits intoy-scope:mainfrom
SharafMohamed:profiler
Open

perf: Add ScopedProfiler and ProfilerReporter to simplify profiling. #2080
SharafMohamed wants to merge 179 commits intoy-scope:mainfrom
SharafMohamed:profiler

Conversation

@SharafMohamed
Copy link
Contributor

@SharafMohamed SharafMohamed commented Mar 6, 2026

Description

This PR significantly simplifies profiling by introducing two new classes:

  • ScopedProfiler - Starts and stops a timer for a given name on construction/destruction.
  • ProfilerReporter - Reports runtime measurements on destruction, including total time, call count, and average time.

Usage:

  1. Declare a ProfilerReporter in main (before any ScopedProfiler instances).
  2. Add the macro PROFILE_SCOPE("scope_name") at the top of any method to track its runtime. This automatically creates a ScopedProfiler.

Changes to Profiler class:

  • Combined continuous and fragmented measurements; their behaviour was effectively identical.
  • Introduced a distinction between Compile-time measurements and Runtime measurements:
    • Compile-time: Used for hot loops, still rely on the old profiling style. Requires calling Profiler::init().
    • Runtime: Used for general profiling, including ScopedProfiler and ProfilerReporter. Does not require calling Profiler::init().
  • Added safety checks for initialization when using compile-time measurements.

Other changes:

  • Enabled PROF_TEST_ENABLED=1 in CMake to ensure profiling is always active during unit-tests.
  • Updated old-style profiling in CLP/CLG/CLO to use the new classes.
  • Update Stopwatch unit-tests to use modern sleep calls and run faster.

Validation Performed

  • Added unit tests for ScopedProfiler.
  • Added unit tests for ProfilerReporter.

Summary by CodeRabbit

  • New Features

    • Added automatic scope-based profiling with runtime measurements, per-call counts and formatted end-of-scope reporting; compile-time probes remain zero-overhead when disabled.
    • Stopwatch now reports call counts and provides a const-safe time query.
  • Tests

    • Added unit tests for profiling utilities and updated timing tests to use modern, finer-grained timing APIs.
  • Chores

    • Test build flag added to enable test-specific profiling paths.

…esting code for DP algo; Add final unit-test for testing PR end-to-end; Still lots of edge cases and sub-steps that could be tested more rigorously.
…e now stored logtype as it will no longer dangle.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 6, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Refactors Profiler to separate runtime (named unordered_map) and compile-time (enum-indexed vector) measurements; adds RAII utilities ProfilerReporter and ScopedProfiler; Stopwatch now tracks call counts; instrumentation switched to PROFILE_SCOPE; tests and CMake updated (adds PROF_TEST_ENABLED).

Changes

Cohort / File(s) Summary
Profiler core
components/core/src/clp/Profiler.hpp, components/core/src/clp/Profiler.cpp
Replaced fragmented/continuous storage with m_runtime_measurements: std::unordered_map<std::string, Stopwatch>, m_compile_time_measurements and m_initialized. Added runtime APIs (start/stop/reset/query/get_call_count), templated compile-time APIs, init()/check_init(), and runtime timer validation. Removed legacy continuous/fragmented APIs and logging macros.
RAII profiling utilities
components/core/src/clp/ProfilerReporter.hpp, components/core/src/clp/ScopedProfiler.hpp
Added clp::ProfilerReporter (RAII reporter that logs or copies runtime measurements) and clp::ScopedProfiler (RAII scope timer). Both are non-copyable/movable; introduced PROFILE_SCOPE macro gated by PROF_ACTIVE.
Stopwatch
components/core/src/clp/Stopwatch.hpp, components/core/src/clp/Stopwatch.cpp
Added m_call_count and get_call_count(); stop() increments call count; get_time_taken_in_seconds() made const with trailing return; headers/typedefs updated (<cstdint>, <chrono>).
Runtime instrumentation changes
components/core/src/clp/clg/clg.cpp, components/core/src/clp/clo/clo.cpp, components/core/src/clp/clp/run.cpp, components/core/src/clp/clp/FileCompressor.cpp
Replaced explicit Profiler::init() and manual continuous measurement start/stop/logging with ProfilerReporter instances and PROFILE_SCOPE usage; removed legacy continuous measurement calls and logging macros.
Build & tests
components/core/CMakeLists.txt, components/core/src/clp/clp/CMakeLists.txt, components/core/tests/test-ProfilerReporter.cpp, components/core/tests/test-ScopedProfiler.cpp, components/core/tests/test-Stopwatch.cpp
Added new headers to CMake sources and set PROF_TEST_ENABLED=1 for unit tests. Added tests for ProfilerReporter and ScopedProfiler; updated Stopwatch tests to use std::chrono/std::thread and adjusted timing expectations.
New files — tests & headers
components/core/src/clp/ProfilerReporter.hpp, components/core/src/clp/ScopedProfiler.hpp, components/core/tests/test-ProfilerReporter.cpp, components/core/tests/test-ScopedProfiler.cpp
New files implement RAII reporter and scoped profiler plus unit tests validating timing and call counts.

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant PR as ProfilerReporter
    participant SP as ScopedProfiler
    participant Prof as Profiler
    participant SW as Stopwatch

    App->>PR: create ProfilerReporter
    App->>SP: enter PROFILE_SCOPE(name)
    SP->>Prof: start_runtime_measurement(name)
    Prof->>SW: create/start stopwatch for name
    Note over SW: elapsed time accumulates
    App->>SP: exit scope
    SP->>Prof: stop_runtime_measurement(name)
    Prof->>SW: record elapsed / increment call_count
    Prof->>Prof: update m_runtime_measurements[name]
    App->>PR: destructor invoked (scope exit)
    PR->>Prof: get_runtime_measurements()
    Prof-->>PR: return measurements map
    PR->>PR: format or copy into sink
    PR-->>App: report measurements (log or sink)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: introducing ScopedProfiler and ProfilerReporter to simplify profiling. It directly reflects the primary objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/core/src/clp/clo/clo.cpp`:
- Around line 575-576: ProfilerReporter is instantiated but no profiling scopes
are used, so it will emit empty measurements; either add PROFILE_SCOPE macros
around meaningful functions (e.g., wrap the search and extract_ir bodies with
PROFILE_SCOPE("search") and PROFILE_SCOPE("extract_ir") respectively) so
ProfilerReporter records data, or remove/defer the ProfilerReporter
instantiation until instrumentation is added, or at minimum add a comment next
to the ProfilerReporter declaration explaining it’s intentional scaffolding;
update the ProfilerReporter usage or add PROFILE_SCOPE calls inside the
corresponding functions (search, extract_ir) to resolve the empty logs.

In `@components/core/src/clp/clp/FileCompressor.cpp`:
- Around line 31-32: Remove the unused using declaration for Profiler: delete
the line "using clp::Profiler;" from FileCompressor.cpp since only
ScopedProfiler (and macros like PROFILE_SCOPE) are used; confirm no remaining
references to Profiler in FileCompressor.cpp and run a build to ensure no symbol
was actually needed before committing.

In `@components/core/src/clp/clp/run.cpp`:
- Around line 18-19: Remove the unused using declaration for clp::Profiler since
Profiler is not referenced in this file and profiling is handled via the
PROFILE_SCOPE macro; keep any needed using clp::ProfilerReporter if it is used
elsewhere in this file (i.e., delete the line containing "using clp::Profiler;"
and leave "using clp::ProfilerReporter;" intact).

In `@components/core/src/clp/Profiler.hpp`:
- Around line 83-92: In check_runtime_timer_exists(std::string const& name) fix
the typo in the SPDLOG_ERROR message ("measurment" -> "measurement") and remove
the extraneous double semicolon after the return false statement so the function
reads a single "return false;" for the error path; verify the check uses
m_runtime_measurements.contains(name) and SPDLOG_ERROR still includes the timer
name for context.

In `@components/core/src/clp/ProfilerReporter.hpp`:
- Around line 20-31: Fix two typos in the class header comment for
ProfilerReporter: change "destructured" to "destructed" in the sentence about
object lifecycle and change "accidentaly" to "accidentally" in the sentence
about copy/move operations; update the comment block near the ProfilerReporter
description so it reads "Once the object is destructed (scope exit), the runtime
measurements are reported." and "prevent accidentally multiple reporting."
referencing the ProfilerReporter class in ProfilerReporter.hpp.
- Around line 1-2: The include guard macro in ProfilerReporter.hpp is
inconsistent: it currently uses CLP_PROFILER_REPORT_HPP; change it to
CLP_PROFILER_REPORTER_HPP everywhere (the `#ifndef/`#define at the top and the
matching `#endif` comment at the bottom) so the macro matches the file/class name
(ProfilerReporter) and avoids future collisions or confusion.

In `@components/core/src/clp/ScopedProfiler.hpp`:
- Around line 43-47: Replace the use of __LINE__ in the PROFILE_SCOPE macro with
a monotonic preprocessor counter to avoid name collisions when the macro is
expanded multiple times on the same source line: update the PROFILE_SCOPE
definition (which uses CLP_CONCAT_IMPL, CLP_CONCAT and the generated identifier
prefix __clp_profile_scope_) to use __COUNTER__ (or a guarded fallback) instead
of __LINE__ so each instantiation gets a unique variable name across the
translation unit.

In `@components/core/src/clp/Stopwatch.cpp`:
- Around line 24-26: Stopwatch::reset currently zeroes only m_time_taken but
leaves m_call_count unchanged; update Stopwatch::reset to also set m_call_count
= 0 so a direct call to Stopwatch::reset on a reused instance clears both time
and call count for consistency with Profiler::reset_runtime_measurements (which
rebuilds Stopwatches via clear()). Ensure you modify the reset() method in the
Stopwatch class to reset both m_time_taken and m_call_count.

In `@components/core/tests/test-ScopedProfiler.cpp`:
- Around line 10-12: Remove the duplicate using declaration for Profiler: in the
test file remove the repeated line "using clp::Profiler;" so that only a single
using clp::Profiler; remains (keep the existing using clp::ScopedProfiler; line
intact); this eliminates the redundant duplicate using statement.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 546f74f9-ad23-47e0-b624-660b7c74b74b

📥 Commits

Reviewing files that changed from the base of the PR and between dbc1799 and 5017b94.

📒 Files selected for processing (15)
  • components/core/CMakeLists.txt
  • components/core/src/clp/Profiler.cpp
  • components/core/src/clp/Profiler.hpp
  • components/core/src/clp/ProfilerReporter.hpp
  • components/core/src/clp/ScopedProfiler.hpp
  • components/core/src/clp/Stopwatch.cpp
  • components/core/src/clp/Stopwatch.hpp
  • components/core/src/clp/clg/clg.cpp
  • components/core/src/clp/clo/clo.cpp
  • components/core/src/clp/clp/CMakeLists.txt
  • components/core/src/clp/clp/FileCompressor.cpp
  • components/core/src/clp/clp/run.cpp
  • components/core/tests/test-ProfilerReporter.cpp
  • components/core/tests/test-ScopedProfiler.cpp
  • components/core/tests/test-Stopwatch.cpp

@SharafMohamed SharafMohamed changed the title feat: RAII profiler to track call counts and report total/average runtime. feat: Add ScopedProfiler and ProfilerReporter for runtime measurements. Mar 6, 2026
@SharafMohamed SharafMohamed changed the title feat: Add ScopedProfiler and ProfilerReporter for runtime measurements. feat: Add ScopedProfiler and ProfilerReporter to simplify profiling. Mar 6, 2026
@SharafMohamed SharafMohamed changed the title feat: Add ScopedProfiler and ProfilerReporter to simplify profiling. perf: Add ScopedProfiler and ProfilerReporter to simplify profiling. Mar 6, 2026
@SharafMohamed SharafMohamed requested a review from a team as a code owner March 7, 2026 02:50
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/core/src/clp/Profiler.hpp`:
- Around line 61-71: The static init() in Profiler.hpp allocates
m_compile_time_measurements with new but never frees it; either document that
this allocation is intentional for process-lifetime usage or add a matching
cleanup path: implement a static deinit() that checks PROF_ACTIVE and
m_initialized, deletes the vector pointed to by m_compile_time_measurements,
sets the pointer to nullptr and clears m_initialized, and ensure callers invoke
deinit() (e.g., during shutdown) so m_compile_time_measurements is properly
freed.
- Around line 23-24: Fix the typo in the comment describing Measurement in
Profiler.hpp: change "fragemented" to "fragmented" in the sentence that begins
"A Measurement can be taken..." so the documentation reads "...accumulate
fragmented measurements into a single total run time." This is purely a comment
change near the Measurement description.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6274c330-87d3-440e-bc65-adb4391f09f4

📥 Commits

Reviewing files that changed from the base of the PR and between 5017b94 and 96fbe97.

📒 Files selected for processing (5)
  • components/core/src/clp/Profiler.hpp
  • components/core/src/clp/ProfilerReporter.hpp
  • components/core/src/clp/ScopedProfiler.hpp
  • components/core/tests/test-ProfilerReporter.cpp
  • components/core/tests/test-ScopedProfiler.cpp

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
components/core/src/clp/clp/run.cpp (2)

162-162: ⚠️ Potential issue | 🟡 Minor

Coding guideline violation: use false == instead of !.

As per coding guidelines, prefer false == <expression> rather than !<expression>.

📝 Proposed fix
-        if (!compression_successful) {
+        if (false == compression_successful) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/core/src/clp/clp/run.cpp` at line 162, The condition uses negation
operator on the boolean variable compression_successful; change the check to use
the coding-guideline form by replacing the if (!compression_successful) test
with if (false == compression_successful) (locate the occurrence in clp::run or
the function containing compression_successful in run.cpp and update that
conditional).

63-63: ⚠️ Potential issue | 🟡 Minor

Coding guideline violation: use false == instead of !.

As per coding guidelines, prefer false == <expression> rather than !<expression>.

📝 Proposed fix
-        if (!command_line_args.get_use_heuristic()) {
+        if (false == command_line_args.get_use_heuristic()) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/core/src/clp/clp/run.cpp` at line 63, Replace the negation
operator usage in the conditional with the coding-guideline-preferred form:
change the if condition that currently reads using
"!command_line_args.get_use_heuristic()" to use "false ==
command_line_args.get_use_heuristic()" instead; locate the check around the use
of command_line_args.get_use_heuristic() in run.cpp and update the condition
accordingly (preserve surrounding logic and braces).
♻️ Duplicate comments (3)
components/core/src/clp/ProfilerReporter.hpp (2)

25-30: ⚠️ Potential issue | 🟡 Minor

Minor documentation typos.

  • Line 25: "destructured" should be "destructed", and "measurmenets" should be "measurements"
  • Line 30: "accidentaly" should be "accidentally"
📝 Proposed fix
- * - Once the object is destructured (scope exit), the runtime measurmenets are reported.
+ * - Once the object is destructed (scope exit), the runtime measurements are reported.
- *  - Copy and move operations are removed to prevent accidentaly multiple reporting.
+ *  - Copy and move operations are removed to prevent accidentally multiple reporting.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/core/src/clp/ProfilerReporter.hpp` around lines 25 - 30, Fix three
typos in the doc comment of ProfilerReporter: change "destructured" to
"destructed", "measurmenets" to "measurements", and "accidentaly" to
"accidentally" in the comment block describing the ProfilerReporter class (the
paragraph that references ScopedProfiler and copy/move operations); no API
changes, just update the text in the ProfilerReporter.hpp comment.

1-2: 🧹 Nitpick | 🔵 Trivial

Include guard naming inconsistency.

The include guard uses CLP_PROFILER_REPORT_HPP but the file is named ProfilerReporter.hpp. Consider using CLP_PROFILER_REPORTER_HPP for consistency.

♻️ Proposed fix
-#ifndef CLP_PROFILER_REPORT_HPP
-#define CLP_PROFILER_REPORT_HPP
+#ifndef CLP_PROFILER_REPORTER_HPP
+#define CLP_PROFILER_REPORTER_HPP

And at line 65:

-#endif  // CLP_PROFILER_REPORT_HPP
+#endif  // CLP_PROFILER_REPORTER_HPP
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/core/src/clp/ProfilerReporter.hpp` around lines 1 - 2, The include
guard macro is inconsistent with the filename: replace the current macro
CLP_PROFILER_REPORT_HPP with CLP_PROFILER_REPORTER_HPP in the `#ifndef` and
`#define` lines and update the matching `#endif` comment (if present) to use
CLP_PROFILER_REPORTER_HPP; ensure any duplicate occurrences of the old macro in
this header are updated to the new CLP_PROFILER_REPORTER_HPP so the guard is
consistent with ProfilerReporter.hpp.
components/core/src/clp/ScopedProfiler.hpp (1)

47-48: 🧹 Nitpick | 🔵 Trivial

Consider using __COUNTER__ for more robust unique identifiers.

The macro uses __LINE__ which will cause name collisions if PROFILE_SCOPE is used twice on the same line (e.g., in a single-line if statement or macro expansion). Using __COUNTER__ (supported by GCC, Clang, and MSVC) would generate globally unique identifiers.

♻️ Proposed enhancement
-#define PROFILE_SCOPE(x) \
-    ::clp::ScopedProfiler CLP_CONCAT(__clp_profile_scope_, __LINE__)(x)
+#define PROFILE_SCOPE(x) \
+    ::clp::ScopedProfiler CLP_CONCAT(__clp_profile_scope_, __COUNTER__)(x)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/core/src/clp/ScopedProfiler.hpp` around lines 47 - 48, The macro
PROFILE_SCOPE currently concatenates using __LINE__ which can collide when used
multiple times on the same line; update the macro in ScopedProfiler.hpp to use
__COUNTER__ instead of __LINE__ (e.g., change PROFILE_SCOPE definition that
creates ::clp::ScopedProfiler CLP_CONCAT(__clp_profile_scope_, __LINE__)(x) to
use __COUNTER__), and add a portable fallback that falls back to __LINE__ only
if __COUNTER__ is not defined so CLP_CONCAT and PROFILE_SCOPE keep generating
unique identifiers across expansions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/core/src/clp/clp/FileCompressor.cpp`:
- Around line 126-128: Remove the unused local variable file_name in
FileCompressor::compress_file: delete the line that assigns string file_name =
std::filesystem::canonical(file_to_compress.get_path()).string(); (and if that
was the only use of std::filesystem in this translation unit, consider also
removing the unused include or using directive). Ensure
PROFILE_SCOPE("FileCompressor::compress_file") remains and no other code
references file_name.

---

Outside diff comments:
In `@components/core/src/clp/clp/run.cpp`:
- Line 162: The condition uses negation operator on the boolean variable
compression_successful; change the check to use the coding-guideline form by
replacing the if (!compression_successful) test with if (false ==
compression_successful) (locate the occurrence in clp::run or the function
containing compression_successful in run.cpp and update that conditional).
- Line 63: Replace the negation operator usage in the conditional with the
coding-guideline-preferred form: change the if condition that currently reads
using "!command_line_args.get_use_heuristic()" to use "false ==
command_line_args.get_use_heuristic()" instead; locate the check around the use
of command_line_args.get_use_heuristic() in run.cpp and update the condition
accordingly (preserve surrounding logic and braces).

---

Duplicate comments:
In `@components/core/src/clp/ProfilerReporter.hpp`:
- Around line 25-30: Fix three typos in the doc comment of ProfilerReporter:
change "destructured" to "destructed", "measurmenets" to "measurements", and
"accidentaly" to "accidentally" in the comment block describing the
ProfilerReporter class (the paragraph that references ScopedProfiler and
copy/move operations); no API changes, just update the text in the
ProfilerReporter.hpp comment.
- Around line 1-2: The include guard macro is inconsistent with the filename:
replace the current macro CLP_PROFILER_REPORT_HPP with CLP_PROFILER_REPORTER_HPP
in the `#ifndef` and `#define` lines and update the matching `#endif` comment (if
present) to use CLP_PROFILER_REPORTER_HPP; ensure any duplicate occurrences of
the old macro in this header are updated to the new CLP_PROFILER_REPORTER_HPP so
the guard is consistent with ProfilerReporter.hpp.

In `@components/core/src/clp/ScopedProfiler.hpp`:
- Around line 47-48: The macro PROFILE_SCOPE currently concatenates using
__LINE__ which can collide when used multiple times on the same line; update the
macro in ScopedProfiler.hpp to use __COUNTER__ instead of __LINE__ (e.g., change
PROFILE_SCOPE definition that creates ::clp::ScopedProfiler
CLP_CONCAT(__clp_profile_scope_, __LINE__)(x) to use __COUNTER__), and add a
portable fallback that falls back to __LINE__ only if __COUNTER__ is not defined
so CLP_CONCAT and PROFILE_SCOPE keep generating unique identifiers across
expansions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b498685b-2eb1-45d8-9847-d6f2d497a0a3

📥 Commits

Reviewing files that changed from the base of the PR and between 96fbe97 and e970893.

📒 Files selected for processing (4)
  • components/core/src/clp/ProfilerReporter.hpp
  • components/core/src/clp/ScopedProfiler.hpp
  • components/core/src/clp/clp/FileCompressor.cpp
  • components/core/src/clp/clp/run.cpp

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/core/src/clp/Profiler.hpp`:
- Around line 58-61: Update the class comment for Profiler to remove the blanket
"must be called before using the class" requirement and state that
Profiler::init() is only required for compile-time measurements; clarify that
the new runtime APIs work without calling Profiler::init(). Reference
Profiler::init() and the runtime APIs in the comment so callers know init is
optional except when using compile-time measurement paths.
- Around line 74-80: check_init() currently logs SPDLOG_ERROR every time
m_initialized is false (on every start/stop/get path); change it to log the
missing-init error only once by adding a one-time guard (e.g. a static
std::atomic<bool> or a static bool protected by std::once_flag) such as
m_init_error_logged and set it when you first detect !m_initialized, then call
SPDLOG_ERROR only when that flag was false and flip it to true; update the same
pattern in the other Profiler methods referenced (the start/stop/get code paths
at the 143-180 region) so all missing-init diagnostics are gated behind the
one-time flag while preserving the existing return of m_initialized and the
PROF_ACTIVE compile-time guard.
- Around line 95-113: The shared m_runtime_measurements unordered_map is not
synchronized: wrap all accesses (start_runtime_measurement,
stop_runtime_measurement, reset_runtime_measurements, check_runtime_timer_exists
and any iteration in ProfilerReporter) with a single mutex to prevent concurrent
container and Stopwatch races, and change get_runtime_measurements() to return a
copy/snapshot of the map (not a live reference) while holding the lock; ensure
PROFILE_SCOPE code paths also use these locked APIs so individual Stopwatch
start/stop calls are protected.

In `@components/core/src/clp/ProfilerReporter.hpp`:
- Around line 34-53: ProfilerReporter currently emits global runtime
measurements accumulated across prior reporter lifetimes; fix this by clearing
the global measurements at the start of the RAII window: in the ProfilerReporter
constructors (both ProfilerReporter() and explicit
ProfilerReporter(std::unordered_map<std::string, Stopwatch>& sink)) call a
reset/clear API on the Profiler (e.g., Profiler::clear_runtime_measurements() or
Profiler::reset_runtime_measurements()) so the profiler map starts empty for
this reporter instance; if such an API doesn't exist, add one that empties the
internal map returned by Profiler::get_runtime_measurements() and invoke it from
the ProfilerReporter constructors while keeping the destructor behavior that
writes into m_sink or logs as-is.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c01dc71e-8df1-4ecc-891c-a700d86c805b

📥 Commits

Reviewing files that changed from the base of the PR and between e970893 and a8074dc.

📒 Files selected for processing (4)
  • components/core/src/clp/Profiler.hpp
  • components/core/src/clp/ProfilerReporter.hpp
  • components/core/src/clp/Stopwatch.cpp
  • components/core/src/clp/clp/FileCompressor.cpp

@SharafMohamed SharafMohamed requested a review from davidlion March 7, 2026 12:17
@junhaoliao junhaoliao added this to the March 2026 milestone Mar 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants