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

Switch internal instrumentation macros to use profiling crate instead, allowing instrumentation with different profilers #5150

Open
wants to merge 30 commits into
base: master
Choose a base branch
from

Conversation

teddemunnik
Copy link

@teddemunnik teddemunnik commented Sep 23, 2024

Hey! I am not sure if this is something that's been considered before and decided against (I couldn't find any PR's or issues).

This change removes the internal profiling macros in library crates and the puffin feature and replaces it with similar functions in the profiling crate. This crate provides a layer of abstraction over various profiler instrumentation crates and allows library users to pick their favorite (supported) profiler.

An additional benefit for puffin users is that dependencies of egui are included in the instrumentation output too (mainly wgpu which uses the profiling crate), so more details might be available when profiling.

A breaking change is that instead of using the puffin feature on egui, users that want to profile the crate with puffin instead have to enable the profile-with-puffin feature on the profiling crate. Similarly they could instead choose to use profile-with-tracy etc.

I tried to add a 'tracy' feature to egui_demo_app in order to showcase , however the /scripts/check.sh currently breaks on mutually exclusive features (which this introduces), so I decided against including it for the initial PR. I'm happy to iterate more on this if there is interest in taking this PR though.

Screenshot showing the additional info for wgpu now available when using puffin
image

Copy link

Preview available at https://egui-pr-preview.github.io/pr/5150-pr/profiling-crate
Note that it might take a couple seconds for the update to show up after the preview_build workflow has completed.

Copy link
Owner

@emilk emilk left a comment

Choose a reason for hiding this comment

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

Looks good overall, but I would prefer not to have the costs of proc-macros for every egui user, if possible.

We should also document the use of profiling somewhere, with at least a line or two in the crate-level docs for egui eframe.

Btw, you can already combine the profiling output of wgpu with the puffin output of eframe/egui if you enable the right features on both :)

@@ -58,9 +58,8 @@ enum AppIconStatus {
///
/// Since window creation can be lazy, call this every frame until it's either successfully or gave up.
/// (See [`AppIconStatus`])
#[profiling::function]
Copy link
Owner

Choose a reason for hiding this comment

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

Proc-macros like these have a tendency to increase build-times. Luckily we can opt-out of them by disabling the default features of the profiling crate

Copy link
Author

Choose a reason for hiding this comment

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

That's a fair point. I don't think the profiling crates currently implements another abstraction that would call puffin::profile_function! under the hood though. So I think we have 3 options here:

  1. Add profiling::function!() macro upstream which would call puffin::profile_function!()
  2. Create our own egui::profile_function!() macro which calls profiling::scope!() with similar internal code to figure out the calling function name as puffin does internally in it's macro.
  3. Use profiling::scope!() and manually type the function name.

Let me know if you have any thoughts on this. I'll have a look and see how feasible option 1 would be tonight

Cargo.toml Outdated Show resolved Hide resolved
@teddemunnik
Copy link
Author

Thank you for the feedback @emilk! I've added crate level docs as suggested for both egui and eframe (let me know if this is what you meant).

Also opened a pull request for the profiling crate about adding a declarative macro so that we can instrument functions without the procmacro feature enabled, let's see if that is something there is interest for.

@teddemunnik
Copy link
Author

profiling 1.0.16 was released a couple of weeks ago with a new declarative macro profiling::function_scope!() which works very similar to the crate::profile_function!() found in egui currently, which allows us to easily replace existing call sites and not make use or the procedural macros feature.

I've merged this PR with upstream and replaced usages of procedural macros with the new declarative macro. @emilk would you mind having another look at this, and seeing if this resolves your concerns?

@@ -28,3 +30,4 @@ env_logger = { version = "0.10", default-features = false, features = [
log = { workspace = true }
puffin = "0.19"
puffin_http = "0.16"
profiling = {workspace = true, features = ["profile-with-puffin"] }
Copy link
Collaborator

@lucasmerlin lucasmerlin Oct 27, 2024

Choose a reason for hiding this comment

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

Always having the profile-with-puffin feature enabled means egui will now always compile puffin, which isn't great. I think instead we should keep the puffin features in the crates and make them enable the profiling/profile-with-puffin feature.

Alternatively we could remove the puffin features and users could just enable the profiling implementation they'd like by enabling the relevant profiling feature themselves.

Also, I don't think we're using the proc macro, so we should set default-features to false.

Copy link
Author

Choose a reason for hiding this comment

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

Note that this cargo.toml is just in the puffin_profiler sample, based on the name it seems pretty reasonable to require it I think. For egui in general default features are disabled and no profiler is enabled by default I believe

Copy link
Author

Choose a reason for hiding this comment

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

I just double checked regarding 'default-features', it's set to false in the workspace, so I don't think it should be necessary to put that in individual crates when they inherit settings from the workspace.

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.

3 participants