gh-138122: Add differential flame graph by ivonastojanovic · Pull Request #145785 · python/cpython
Differential flame graphs compare two profiling runs and highlight where performance has changed. This makes it easier to detect regressions introduced by code changes and to verify that optimizations have the intended effect. The visualization renders the current profile with frame widths representing current time consumption. Color is then applied to show the difference relative to the baseline profile: red gradients indicate regressions, while blue gradients indicate improvements. Some call paths may disappear entirely between profiles. These are referred to as elided stacks and occur when optimizations remove code paths or when certain branches stop executing. When elided stacks are present, an "Elided" toggle is displayed, allowing the user to switch between the main differential view and a view showing only the removed paths.
ivonastojanovic
changed the title
Add differential flame graph
gh-138122: Add differential flame graph
Use four gradients consistently for both regressions and improvements. Also avoid calling getComputedStyle(document.documentElement) on every frame, cache the values like we do for the heatmap, since doing this per frame can be expensive for large profiles.
Since baseline and current self time are shown in ms, the diff should also be displayed in ms instead of samples.
We were determining the selected data and applying filtering/processing inside each toggle handler, which led to inconsistencies (e.g. thread filtering) and missed cases. This approach also won’t scale well as we add more toggles. Instead, introduce a single centralized function that returns the active flamegraph data and use it consistently for all updates and processing.
Clean up tests by extracting repeated logic (resolving function names and finding child nodes by name) into helper functions. Also add a test that doesn’t mock BinaryCollector to cover the full round trip.
Use purple (with gradients) for both removed and new functions to unify these “out-of-band” cases under a single visual language, meaning no direct comparison is available. This keeps them clearly separate from the red/blue performance axis and simplifies the legend: “purple = this function has no counterpart in the other profile.”
Opcodes from multiple call paths were silently dropped, only the first path's opcodes were kept. Now they're summed correctly when nodes merge.
clin1234 pushed a commit to clin1234/cpython that referenced this pull request
Differential flame graphs compare two profiling runs and highlight where performance has changed. This makes it easier to detect regressions introduced by code changes and to verify that optimizations have the intended effect. The visualization renders the current profile with frame widths representing current time consumption. Color is then applied to show the difference relative to the baseline profile: red gradients indicate regressions, while blue gradients indicate improvements. Some call paths may disappear entirely between profiles. These are referred to as elided stacks and occur when optimizations remove code paths or when certain branches stop executing. When elided stacks are present, an "Elided" toggle is displayed, allowing the user to switch between the main differential view and a view showing only the removed paths. Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
ljfp pushed a commit to ljfp/cpython that referenced this pull request
Differential flame graphs compare two profiling runs and highlight where performance has changed. This makes it easier to detect regressions introduced by code changes and to verify that optimizations have the intended effect. The visualization renders the current profile with frame widths representing current time consumption. Color is then applied to show the difference relative to the baseline profile: red gradients indicate regressions, while blue gradients indicate improvements. Some call paths may disappear entirely between profiles. These are referred to as elided stacks and occur when optimizations remove code paths or when certain branches stop executing. When elided stacks are present, an "Elided" toggle is displayed, allowing the user to switch between the main differential view and a view showing only the removed paths. Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters