Fix accounting of macro expansion times and expanded nodes for the `show-profiles` flag
Fixes #97
This PR rectifies filling in the data by adjusting the current approach, so I'm not 100% confident about the resulting data's accuracy. At the very least, it seems meaningful. After applying these changes, the output when leveraging the show-profiles flag looks like this:
[info] RangePosition(/scala-steward/modules/core/src/main/scala/org/scalasteward/core/git/CommitMsg.scala, 2468, 2468, 2538) -> MacroInfo(
[info] expandedMacros = 1,
[info] expandedNodes = 0,
[info] expansionTime = 104 microseconds
[info] ),
[info] RangePosition(/scala-steward/modules/core/src/main/scala/org/scalasteward/core/buildtool/scalacli/ScalaCliAlg.scala, 3149, 3149, 3163) -> MacroInfo(
[info] expandedMacros = 1,
[info] expandedNodes = 0,
[info] expansionTime = 298 microseconds
[info] ),
[info] source-/scala-steward/modules/core/src/main/scala/org/scalasteward/core/data/DependencyInfo.scala,line-29,offset=913 -> MacroInfo(
[info] expandedMacros = 9,
[info] expandedNodes = 26,
[info] expansionTime = 182 microseconds
[info] ),
[info] source-/scala-steward/modules/core/src/main/scala/org/scalasteward/core/data/Update.scala,line-247,offset=8335 -> MacroInfo(
[info] expandedMacros = 10,
[info] expandedNodes = 29,
[info] expansionTime = 163 microseconds
[info] ),
@DSlug It'd be nice if you could validate this.
The output mostly looks good to me, but there seems to be some undercounting related to high numbers of expansions. I don't really understand how the code works, but it seems you're only tracking self time right now. I think it'd be better to track total expansion time (or both).
For the example I posted in the issue, macro expansion takes about a second, but the macro data indicates a far lower duration:
[info] time spent in macroExpand : 384 spans, ()944.45ms (92.0%)
[info] Macro data per call-site:
[info] Map(
[info] NoPosition -> MacroInfo(14, 178, 369 microseconds),
[info] source-C:\Dev\profiler\src\main\scala\Main.scala,line-6,offset=185 -> MacroInfo(
[info] 110,
[info] 383,
[info] 52718 microseconds
[info] )
[info] )
[info] Macro data per file:
[info] Map(
[info] <no source file> -> MacroInfo(14, 178, 0 milliseconds),
[info] Main.scala -> MacroInfo(110, 383, 52 milliseconds)
[info] )
[info] Macro data in total:
[info] MacroInfo(124, 561, 52 milliseconds)
For comparison, I'd made an attempt at fixing the issue by putting the old code back into ProfilingImpl, which I've pushed here, which comes closer to the time spent in macroExpand (expansionTime is in nanoseconds here):
[info] time spent in macroExpand : 384 spans, ()2358.127ms (85.7%)
[info] precise time in macroExpand : 384 spans, ()2359.534ms
[info] Map(
[info] NoPosition -> MacroInfo(14, 0, 438807900L),
[info] source-C:\Dev\profiler\src\main\scala\Main.scala,line-6,offset=185 -> MacroInfo(110, 0, 2359534400L)
[info] )
[info] Macro data per file:
[info] Map(
[info] <no source file> -> MacroInfo(14, 0, 438807900L),
[info] Main.scala -> MacroInfo(110, 0, 2359534400L))
[info] Macro data in total:
[info] MacroInfo(124, 0, 2798342300L)
I've run both versions on scala-steward, you can see that the numbers are fairly close when expandedMacros = 1, and diverge greatly otherwise:
[info] RangePosition(C:\Dev\scala-steward\modules\core\src\main\scala\org\scalasteward\core\git\CommitMsg.scala, 2468, 2468, 2538)
-> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 146 microseconds),
[info] RangePosition(C:\Dev\scala-steward\modules\core\src\main\scala\org\scalasteward\core\git\CommitMsg.scala, 2468, 2468, 2538)
-> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionNanos = 168500L),
[info] RangePosition(C:\Dev\scala-steward\modules\core\src\main\scala\org\scalasteward\core\buildtool\scalacli\ScalaCliAlg.scala, 3149, 3149, 3163)
-> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 193 microseconds),
[info] RangePosition(C:\Dev\scala-steward\modules\core\src\main\scala\org\scalasteward\core\buildtool\scalacli\ScalaCliAlg.scala, 3149, 3149, 3163)
-> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionNanos = 634700L),
[info] source-C:\Dev\scala-steward\modules\core\src\main\scala\org\scalasteward\core\application\Context.scala,line-98,offset=4329
-> MacroInfo(expandedMacros = 2, expandedNodes = 2, expansionTime = 133 microseconds),
[info] source-C:\Dev\scala-steward\modules\core\src\main\scala\org\scalasteward\core\application\Context.scala,line-98,offset=4329
-> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionNanos = 3187600L),
[info] source-C:\Dev\scala-steward\modules\core\src\main\scala\org\scalasteward\core\data\DependencyInfo.scala,line-29,offset=913
-> MacroInfo(expandedMacros = 9,expandedNodes = 26,expansionTime = 121 microseconds),
[info] source-C:\Dev\scala-steward\modules\core\src\main\scala\org\scalasteward\core\data\DependencyInfo.scala,line-29,offset=913
-> MacroInfo(expandedMacros = 9, expandedNodes = 0, expansionNanos = 72669100L),
[info] source-C:\Dev\scala-steward\modules\core\src\main\scala\org\scalasteward\core\data\Update.scala,line-247,offset=8335
-> MacroInfo(expandedMacros = 10, expandedNodes = 29, expansionTime = 99 microseconds),
[info] source-C:\Dev\scala-steward\modules\core\src\main\scala\org\scalasteward\core\data\Update.scala,line-247,offset=8335
-> MacroInfo(expandedMacros = 10, expandedNodes = 0, expansionNanos = 55140100L),
@DSlug Thank you for such detailed research! I accidentally missed that the 'time in macro expand' significantly differs from the sum of the macro calls per file. That is a crucial part. We can have some tolerated error when comparing these two numbers, I guess. But it barely should be greater than 10%. Will try to take a deeper dive into this.
@DSlug It's been a while, but I had some time on the past weekends and tried to apply your changes to the current master. Unfortunately, I got worse results — no information about macro expansions at all. Maybe I did something wrong, but that's how it is.
[info] Macro data per file:
[info] HashMap(
[info] Timestamp.scala -> MacroInfo(expandedMacros = 4, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] JsonKeyValueStore.scala -> MacroInfo(
[info] expandedMacros = 3,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] VersionPositionScanner.scala -> MacroInfo(
[info] expandedMacros = 5,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] NewPullRequestData.scala -> MacroInfo(
[info] expandedMacros = 32,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] PruningAlg.scala -> MacroInfo(expandedMacros = 6, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] UpdateInfoUrlFinder.scala -> MacroInfo(
[info] expandedMacros = 1,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] SbtVersion.scala -> MacroInfo(expandedMacros = 4, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ScalafixMigration.scala -> MacroInfo(
[info] expandedMacros = 18,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] TokenOut.scala -> MacroInfo(expandedMacros = 8, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ScalafmtConfig.scala -> MacroInfo(
[info] expandedMacros = 18,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] RepoCache.scala -> MacroInfo(expandedMacros = 11, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] RunResults.scala -> MacroInfo(expandedMacros = 4, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] CommitsConfig.scala -> MacroInfo(expandedMacros = 18, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] RepoOut.scala -> MacroInfo(expandedMacros = 14, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] GitHubAssignees.scala -> MacroInfo(
[info] expandedMacros = 8,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] UpdatePullRequestPayload.scala -> MacroInfo(
[info] expandedMacros = 9,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] PullRequestNumber.scala -> MacroInfo(
[info] expandedMacros = 4,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] Json.scala -> MacroInfo(expandedMacros = 138, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ProcessAlg.scala -> MacroInfo(expandedMacros = 4, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] PullRequestGroup.scala -> MacroInfo(
[info] expandedMacros = 20,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] BuildToolDispatcher.scala -> MacroInfo(
[info] expandedMacros = 1,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] package.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] PostUpdateHookConfig.scala -> MacroInfo(
[info] expandedMacros = 30,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] GitHubApiAlg.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] HttpJsonClient.scala -> MacroInfo(expandedMacros = 4, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] dateTime.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] logger.scala -> MacroInfo(expandedMacros = 7, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] UpdatePattern.scala -> MacroInfo(expandedMacros = 10, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ArtifactChanges.scala -> MacroInfo(
[info] expandedMacros = 17,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] package.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ScalafixMigrations.scala -> MacroInfo(
[info] expandedMacros = 18,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] ValidateRepoConfigAlg.scala -> MacroInfo(
[info] expandedMacros = 6,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] package.scala -> MacroInfo(expandedMacros = 3, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Update.scala -> MacroInfo(expandedMacros = 60, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Version.scala -> MacroInfo(expandedMacros = 4, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Context.scala -> MacroInfo(expandedMacros = 5, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ScalaCliAlg.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] GroupRepoConfig.scala -> MacroInfo(
[info] expandedMacros = 12,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] VersionPattern.scala -> MacroInfo(
[info] expandedMacros = 22,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] Scope.scala -> MacroInfo(expandedMacros = 9, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] StewardAlg.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] CommitOut.scala -> MacroInfo(expandedMacros = 8, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] WorkspaceAlg.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ClientConfiguration.scala -> MacroInfo(
[info] expandedMacros = 6,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] GiteaApiAlg.scala -> MacroInfo(expandedMacros = 139, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ArtifactMigrationsLoader.scala -> MacroInfo(
[info] expandedMacros = 4,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] DependencyInfo.scala -> MacroInfo(expandedMacros = 9, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] UpdatesConfig.scala -> MacroInfo(expandedMacros = 40, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] GitHubAppApiAlg.scala -> MacroInfo(
[info] expandedMacros = 2,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] UpdateState.scala -> MacroInfo(expandedMacros = 8, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] UrlChecker.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] RefreshErrorAlg.scala -> MacroInfo(
[info] expandedMacros = 10,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] ReposFilesLoader.scala -> MacroInfo(
[info] expandedMacros = 4,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] CrossDependency.scala -> MacroInfo(
[info] expandedMacros = 4,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] CreatePullRequestPayload.scala -> MacroInfo(
[info] expandedMacros = 12,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] UpdateState.scala -> MacroInfo(expandedMacros = 6, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] NurtureAlg.scala -> MacroInfo(expandedMacros = 15, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] BitbucketServerApiAlg.scala -> MacroInfo(
[info] expandedMacros = 2,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] UserOut.scala -> MacroInfo(expandedMacros = 8, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] SbtAlg.scala -> MacroInfo(expandedMacros = 3, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Reviewer.scala -> MacroInfo(expandedMacros = 16, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ForgeApiAlg.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] GitHubLabels.scala -> MacroInfo(expandedMacros = 8, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Url.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ScalaVersion.scala -> MacroInfo(expandedMacros = 4, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Url.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ForgeType.scala -> MacroInfo(expandedMacros = 8, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] BranchOut.scala -> MacroInfo(expandedMacros = 9, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Comment.scala -> MacroInfo(expandedMacros = 8, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] GitLabApiAlg.scala -> MacroInfo(expandedMacros = 62, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ArtifactId.scala -> MacroInfo(expandedMacros = 9, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] parser.scala -> MacroInfo(expandedMacros = 3, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Details.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] VersionsCache.scala -> MacroInfo(expandedMacros = 10, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] HookExecutor.scala -> MacroInfo(expandedMacros = 6, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ScalafmtAlg.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Cli.scala -> MacroInfo(expandedMacros = 26, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] JsonCodec.scala -> MacroInfo(expandedMacros = 38, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] FilterAlg.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] FileAlg.scala -> MacroInfo(expandedMacros = 3, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] MillAlg.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] CreatePullRequestRequest.scala -> MacroInfo(
[info] expandedMacros = 1,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] string.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ModulePositionScanner.scala -> MacroInfo(
[info] expandedMacros = 3,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] RepositoriesOut.scala -> MacroInfo(
[info] expandedMacros = 16,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] process.scala -> MacroInfo(expandedMacros = 13, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] package.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] SelfCheckAlg.scala -> MacroInfo(expandedMacros = 6, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] RepoConfigLoader.scala -> MacroInfo(
[info] expandedMacros = 5,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] Dependency.scala -> MacroInfo(expandedMacros = 13, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Author.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] command.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] CreateComment.scala -> MacroInfo(expandedMacros = 16, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] EditAlg.scala -> MacroInfo(expandedMacros = 3, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] InstallationOut.scala -> MacroInfo(
[info] expandedMacros = 8,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] RepoConfigAlg.scala -> MacroInfo(expandedMacros = 6, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] RepoConfig.scala -> MacroInfo(expandedMacros = 54, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] RepoCacheAlg.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] package.scala -> MacroInfo(expandedMacros = 3, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ForgeRepoAlg.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] PullRequestRepository.scala -> MacroInfo(
[info] expandedMacros = 13,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] ScalafixMigrationsLoader.scala -> MacroInfo(
[info] expandedMacros = 4,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] AzureReposApiAlg.scala -> MacroInfo(
[info] expandedMacros = 1,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] ForgeAuthAlg.scala -> MacroInfo(expandedMacros = 1, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] FileGitAlg.scala -> MacroInfo(expandedMacros = 3, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] PullRequestsConfig.scala -> MacroInfo(
[info] expandedMacros = 31,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] CommitMsg.scala -> MacroInfo(expandedMacros = 7, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] SemVer.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] BuildToolAlg.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] ArtifactChange.scala -> MacroInfo(
[info] expandedMacros = 26,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] PullRequestOut.scala -> MacroInfo(
[info] expandedMacros = 11,
[info] expandedNodes = 0,
[info] expansionTime = 0 milliseconds
[info] ),
[info] Sha1.scala -> MacroInfo(expandedMacros = 12, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] Resolver.scala -> MacroInfo(expandedMacros = 135, expandedNodes = 0, expansionTime = 0 milliseconds),
[info] CoursierAlg.scala -> MacroInfo(expandedMacros = 2, expandedNodes = 0, expansionTime = 0 milliseconds)
[info] )
[info] Macro data in total:
[info] MacroInfo(expandedMacros = 1453, expandedNodes = 0, expansionTime = 0 nanoseconds)
@DSlug It'd be great if you had time to create a separate PR on top of that one.
@danicheg What do you want me to make a PR of, exactly?
@DSlug Yeah, if you can create a full-fledged PR, it'd be good.