Unity-Technologies / ProjectAuditor

Project Auditor is an experimental static analysis tool for Unity Projects.
Other
795 stars 64 forks source link

Draft of ProfilerAnalyzer to scan ProfilerDriver markers #170

Closed borisbauer-unity closed 1 year ago

borisbauer-unity commented 1 year ago

Description

Draft of reusable code to gather important markers from the ProfilerDriver API.

Changes made

Added ProfilerAnalyzer class with basic logic to traverse and gather several known Profiler markers from ProfilerDrivers's HierarchyFrameDataView API (hierarchical access to profiler markers).

Notes

TODO

MarkerDefinitions array:

CalculateFrametimeStats method:

Checklist

TODO: Before changing API docs, etc get PR draft to a stage where code and naming is improved / final.

Before review

borisbauer-unity commented 1 year ago

Sounds good!

  • It should be pretty straightforward to make this data driven.

Definitely could be data-driven, e.g. feeding the MarkerDefinitions as a parameter coming from a (json or ScriptableObject) file.

I have the feeling that markers could definitely be something teams/users may want to extend, e.g. either they want to add/update more built-in and 3rd party markers or they have a lot of interesting markers in their custom code. Then they add those few markers and categorize them with a new keyword (which may be its own category for a frame breakdown or a sub-category of Behaviours since they wrote everything in MonoBehaviours). That could be a workflow in the UX or to keep it simple first adding/editing it in a .json file.

  • The ProfileAnalyzer class should probably provide an API to search for a specific marker (defined by MarkerDefinition). I am not quite sure if that should return a collection of frame/marker data or something else.

Yes, I thought about this general query:

The caller wants to check if any frames had a certain marker. To implement this query efficiently for any number of frames I'd probably hash markers per frame so it is very fast if that query comes in several times (let's say for a few dozen methods that Analyzers report, and then want to query if that marker or any on the callstack was in any of the many frames we captured).

The return value could be: All found MarkerStats for each frame (MarkerStats containing timings and MarkerDefinition), so we can also average or otherwise summarize timings and counters over various frames.

My other query I handle in a GA view so far is this:

For each frame return me the markers falling into one category.

Queries in summary: A general query could just return one array element for each frame (or only frames with actual matches, also indicating the frame index), and per such frame element containing an array of MarkerStats that were gathered by executing a lambda (MarkerStat = timings + MarkerDefinition).

Then we wrap this query for convencience, one query for a MarkerDefinition, one for a marker Category.

mtrive commented 1 year ago

closing for the time being