Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a CodeTimer stack #4518

Merged

Conversation

kwvanderlinde
Copy link
Collaborator

@kwvanderlinde kwvanderlinde commented Dec 3, 2023

Identify the Bug or Feature request

implements #4514

Description of the Change

A new per-thread stack of CodeTimer is available to allow getting a CodeTimer from anywhere. The top of the stack is always available by calling the CodeTimer.get() static method. When a section of code needs to be timed with a report, CodeTimer.using(name, callback) is used. This method creates a new timer, enables it if necessary, pushes it onto the stack, runs the callback, pops the timer back off the stack, and generates a report. In other words, it runs the callback during which a new timer is available via CodeTimer.get(), then reports the results.

Additional changes include cleaning up CodeTimer by removing unused bits, making the start()/stop() methods leaner in terms of its HashMap<> usage, and allowing dynamic IDs to clean up some calling code.

I would advise ignoring whitespace in the diff, as the use of CodeTimer.using() has modified the indentation of the code.

Possible Drawbacks

Should be none.

Documentation Notes

N/A

Release Notes

  • Added a stack of CodeTimer to make timing of code easier.

This change is Reviewable

The `orderMap` field was removed as it was only responsible for maintaining the insertion order of timer IDs. This is
now accomplished more cheaply by changing `timeMap` to `LinkedHashMap<>`. This saves some extra hash table reads and
writes, and also means we don't need to explicitly sort IDs during reporting.

There were a couple places where we did redundant key lookups on `timeMap`, to handle cases where the key may or may not
already exist. These were modified to instead do a single key lookup, via `computeIfAbsent()` and `get()`.
This is inspired by loggers, though based on `String.format()`. It allows using timers with dynamic names without
needing to clutter calling code with `CodeTimer.isEnabled()` checks to avoid the overhead when not needed.

The few places that used `CodeTimer.isEnabled()` for this purpose have been updated to use the parameterized form, and
`isEnabled()` is now only used to check if timings should be reported.
Each thread has a stack of `CodeTimer`, with the top of the stack being available anywhere via a call to
`CodeTimer.get()`. When a different timer is needed for a section of code, `CodeTimer.using()` will push a new timer
onto the stack, and pop it off the stack when the timed code completes, restoring the previous timer.

`CodeTimer.using()` also takes care of enabling the new timer based on `AppState.isCollectProfilingData()`, and
reporting the results at the end if the timer is enabled. This saves some repeated logic and adds a bit of consistency
in how timers are used.
All affected components followed the same basic pattern, with some variations:
1. Create the timer.
2. Enable / disable the timer, usually based on AppState.
3. Set a minimum threshold.
4. At the end, report to the profiling frame.

Now (1), (2) and (4) are done automatically and consistently in `CodeTimer.using()`, with (2) and (3) also doable by the
caller to customize the timer as needed.
@cwisniew cwisniew added this pull request to the merge queue Dec 7, 2023
@cwisniew cwisniew added the refactor Refactoring the code for optimal awesomeness. label Dec 7, 2023
Merged via the queue into RPTools:develop with commit 9b948b4 Dec 7, 2023
4 checks passed
@kwvanderlinde kwvanderlinde deleted the refactor/4514-scoped-code-timers branch January 9, 2024 09:12
@cwisniew cwisniew added the code-maintenance Adding/editing javadocs, unit tests, formatting. label Mar 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code-maintenance Adding/editing javadocs, unit tests, formatting. refactor Refactoring the code for optimal awesomeness.
Projects
Development

Successfully merging this pull request may close these issues.

2 participants