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

Add profiler under a flag #2765

Merged
merged 8 commits into from
Dec 8, 2017
Merged

Add profiler under a flag #2765

merged 8 commits into from
Dec 8, 2017

Conversation

smera
Copy link
Contributor

@smera smera commented Dec 1, 2017

Adding an evaluation profiler, enabled via a command line flag (/profileevaluation:file).
When turned on, it generates a report after the build finishes. See documentation/evaluation-profiling.md for more details

@dnfclas
Copy link

dnfclas commented Dec 1, 2017

@smera,
Thanks for your contribution.
To ensure that the project team has proper rights to use your work, please complete the Contribution License Agreement at https://cla2.dotnetfoundation.org.

It will cover your contributions to all .NET Foundation-managed open source projects.
Thanks,
.NET Foundation Pull Request Bot
#Resolved

@dnfclas
Copy link

dnfclas commented Dec 1, 2017

@smera, thanks for signing the contribution license agreement. We will now validate the agreement and then the pull request.

Thanks, .NET Foundation Pull Request Bot #Resolved

@@ -1,6 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Copy link
Contributor

@cdmihai cdmihai Dec 1, 2017

Choose a reason for hiding this comment

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

Can you please revert all the spurious changes that VS did to this file? :)
I edit the resx files from vscode to make sure VS does not dirty them up. #Resolved

Copy link
Contributor Author

@smera smera Dec 1, 2017

Choose a reason for hiding this comment

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

sure #Resolved

/// <summary>
/// Generates a markdown file on disk with the result of profiling the evaluation
/// </summary>
private static void GenerateProfilerReport(ProfilerLogger profilerLogger)
Copy link
Contributor

@AndyGerlicher AndyGerlicher Dec 1, 2017

Choose a reason for hiding this comment

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

Should this logic go in the ProfileLogger? On shutdown or something? #Resolved

Copy link
Contributor Author

@smera smera Dec 1, 2017

Choose a reason for hiding this comment

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

I intendedly kept the file saving part outside of the profiler logger because I was seeing the logger more as a collector of data. But I can move the saving logic inside. #Resolved

@AndyGerlicher
Copy link
Contributor

AndyGerlicher commented Dec 1, 2017

This is looking really good!!

Minor thing, I like that xmake knows how to parse the params to turn on the profiling and create the logger, but I don't think writing the file should be there. That should happen on shutdown like a normal file logger would. So the logger is just something that happens to listen for that data and writes it out in the default format it knows about.

@KirillOsenkov seems like we should just add this to the binary logger file. Would be easy to do, and could even have a nice visualization someday? And we're changing the format anyway seems no harm in adding that. So in that case maybe /prof by itself would turn the feature on but not attach the ProfileLogger? And then the binary logger would pick them up and write them to the file? So you would build msbuild /bl /prof. And later you could msbuild msbuild.binlog /prof:file.md to get the default experience. I'm also curious what perf impact this has if we should force /prof on when /bl is specified similar to other things. But we'd need some numbers to know that. My guess is it's not that bad though, esp. when you're doing a debug build.

@mmitche any idea what's wrong with our CI? None of the jobs are reporting status apparently. Not sure how to debug that without links to them. #Resolved



/// <summary>
/// The outer xml markup of the xml element associated with this project element/>
Copy link
Contributor

@AndyGerlicher AndyGerlicher Dec 1, 2017

Choose a reason for hiding this comment

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

remove /> #Resolved

Copy link
Contributor Author

@smera smera Dec 1, 2017

Choose a reason for hiding this comment

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

Will do #Resolved

@AndyGerlicher
Copy link
Contributor

AndyGerlicher commented Dec 1, 2017

@mmitche
Copy link
Member

mmitche commented Dec 1, 2017

They look like they are reporting now. #Resolved

@mmitche
Copy link
Member

mmitche commented Dec 1, 2017

@AndyGerlicher ci2 was offline for a bit while a server move was happening. #Resolved

@KirillOsenkov
Copy link
Member

KirillOsenkov commented Dec 1, 2017

I've filed #2768 to track this.

Would indeed be nice to serialize this info to the .binlog if available. @smera if you have cycles would be awesome if you could get to it (perhaps as part of a separate PR). I can come down and explain how binlog serialization works, it's not hard. We can maybe even write it together. #Resolved

@@ -63,6 +71,9 @@
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Xml" />
Copy link
Contributor

@cdmihai cdmihai Dec 1, 2017

Choose a reason for hiding this comment

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

Please transform this into a nuget dependency instead (project.json file next to this csproj). Mixing nuget and these leads to confusing dependency resolution. #Resolved

Copy link
Contributor Author

@smera smera Dec 2, 2017

Choose a reason for hiding this comment

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

Ah, that may explain some warnings I was seeing. Will change, thanks! #Resolved

/// </summary>
[MemberData(nameof(GetProfilerResults))]
[Theory]
public void ProfilerResultRoundTrip(ProfilerResult profilerResult)
Copy link
Contributor

@cdmihai cdmihai Dec 2, 2017

Choose a reason for hiding this comment

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

Shouldn't this test go in a new ProjectEvaluationFinishedEventArgs_Tests class instead? #Resolved

Copy link
Contributor Author

@smera smera Dec 2, 2017

Choose a reason for hiding this comment

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

Yeap, good catch #Resolved

IDictionary<EvaluationLocation, ProfiledLocation> profiledLocations = new Dictionary<EvaluationLocation, ProfiledLocation>();
if (translator.Mode == TranslationDirection.WriteToStream)
{
profiledLocations = profilerResult.ProfiledLocations.ToDictionary(kv => kv.Key, kv => kv.Value);
Copy link
Contributor

@cdmihai cdmihai Dec 2, 2017

Choose a reason for hiding this comment

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

This ToDictionary might take some time / memory. How bad would it get if you made ProfilerResult.ProfiledLocations an ImmutableDictionary instead? That one implements IDictionary, and should not need the extra ToDictionary call. #Resolved

Copy link
Contributor Author

@smera smera Dec 2, 2017

Choose a reason for hiding this comment

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

I usually prefer IReadOnlyDictionary since the immutability is clearer. Plus this is not in the hot path: it only takes place when the profiler is on, and after an evaluation is done. But if you feel strong about it, I don't mind changing it. #Resolved

Copy link
Contributor

@cdmihai cdmihai Dec 2, 2017

Choose a reason for hiding this comment

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

let's leave it like this until it becomes a measurable problem :) #Resolved

/// <summary>
/// The outer xml markup of the xml element associated with this project element/>
/// </summary>
string OuterXmlElement { get; }
Copy link
Contributor

@cdmihai cdmihai Dec 2, 2017

Choose a reason for hiding this comment

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

Can you rename this to hide the fact that it's XML? Maybe OuterElement or RawElementRepresentation, or RawText #Resolved

Copy link
Contributor Author

@smera smera Dec 2, 2017

Choose a reason for hiding this comment

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

Mmhh.. but this was originally being retrieved directly as this.XmlElement.OuterXml. So I thought it was important to communicate the original provenance. I would have exposed XmlElementWithLocation directly (the type of XmlElement), but that needed an extra project reference, and avoiding that was the main purpose of this interface.
But I'm not well versed in the content of a ProjectElement, so I'll follow your advice here. #Resolved

Copy link
Contributor

@cdmihai cdmihai Dec 2, 2017

Choose a reason for hiding this comment

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

The ProjectElement wraps over an XmlElement. It is like an MSBuild AST node. I was thinking that if we ever change MSBuild's representation from XML to something else (probably never, but who knows), then having an interface member referencing XML would be cumbersome. #Resolved

Copy link
Contributor Author

@smera smera Dec 2, 2017

Choose a reason for hiding this comment

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

Ok, makes sense, will change #Resolved

@smera
Copy link
Contributor Author

smera commented Dec 2, 2017

@andy Gerlicher, moved the saving part to the logger


In reply to: 348609891 [](ancestors = 348609891)

@smera
Copy link
Contributor Author

smera commented Dec 2, 2017

I'll try to address that as a separate PR


In reply to: 348642187 [](ancestors = 348642187)

/// </summary>
[InlineData(" ")]
[InlineData("a_file_with?invalid_chars")]
[InlineData("C:\\a_path\\with?invalid\\chars")]
Copy link
Contributor

@AndyGerlicher AndyGerlicher Dec 2, 2017

Choose a reason for hiding this comment

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

These aren't all invalid on other OSs which is why the tests are failing. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will make this test Windows-specific. Just trying to validate there is a validation going on around invalid chars, so any OS will do


In reply to: 154504123 [](ancestors = 154504123)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the end I made it slightly more generic to cover other OSs too


In reply to: 154737571 [](ancestors = 154737571,154504123)

Copy link
Contributor

@AndyGerlicher AndyGerlicher left a comment

Choose a reason for hiding this comment

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

Very nice!

@AndyGerlicher
Copy link
Contributor

@dotnet-bot test this please

Odd they all timed out except the full framework build...

@AndyGerlicher
Copy link
Contributor

@dotnet-bot test this please

1 similar comment
@smera
Copy link
Contributor Author

smera commented Dec 6, 2017

@dotnet-bot test this please

@AndyGerlicher
Copy link
Contributor

@dotnet-bot test Windows_NT Build for CoreCLR please

AndyGerlicher and others added 4 commits December 7, 2017 11:19
* A bool was attempted to be read twice when reading from the stream.
* On read, val.Value was called when null causing an exception.

Unrelated to this, if an exception happens during the translate process all the nodes hang.
@AndyGerlicher
Copy link
Contributor

Green CI!!! :)

@AndyGerlicher AndyGerlicher changed the title [WIP] Add profiler under a flag Add profiler under a flag Dec 8, 2017
@AndyGerlicher AndyGerlicher merged commit 36e9ed6 into dotnet:master Dec 8, 2017
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.

6 participants