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

Use a pooled StringBuilder in Dependency.GetID #3129

Merged
merged 2 commits into from
Jan 23, 2018

Conversation

Pilchie
Copy link
Member

@Pilchie Pilchie commented Jan 11, 2018

Traces showed this taking upward of 1% of allocations of opening a solution.

Fixes #2918.

**Customer scenario**

What does the customer do to get into this situation, and why do we think this
is common enough to address in Escrow. (Granted, sometimes this will be
obvious "Open project, VS crashes" but in general, I need to understand how
common a scenario is)

Bugs this fixes:

(either VSO or GitHub links)

Workarounds, if any

Also, why we think they are insufficient for RC vs. RC2, RC3, or RTW

Risk

This is generally a measure our how central the affected code is to adjacent
scenarios and thus how likely your fix is to destabilize a broader area of code

Performance impact

(with a brief justification for that assessment (e.g. "Low perf impact because no extra allocations/no complexity changes" vs. "Low")

Is this a regression from a previous update?

Root cause analysis:

How did we miss it? What tests are we adding to guard against it in the future?

How was the bug found?

(E.g. customer reported it vs. ad hoc testing)

@Pilchie Pilchie requested review from davkean, abpiskunov, natidea and a team January 11, 2018 18:24
@Pilchie
Copy link
Member Author

Pilchie commented Jan 11, 2018

Tagging @lifengl for review.

Also @tmat - is there a way to re-use Roslyn's object pooling stuff instead of making my own?

@tmat
Copy link
Member

tmat commented Jan 11, 2018

Certainly. Add a package reference to Microsoft.CodeAnalysis.PooledObjects.

@tmat
Copy link
Member

tmat commented Jan 11, 2018

You might also want to add a workaround for NuGet/Home#4856 to the project that will reference the source package:

<ItemGroup>
    <Compile Update="@(Compile)">
      <Link Condition="'%(NuGetPackageId)' != ''">%(NuGetPackageId)\%(Link)</Link>
    </Compile>
</ItemGroup>

@Pilchie
Copy link
Member Author

Pilchie commented Jan 11, 2018

@tmat is it only on myget?

@tmat
Copy link
Member

tmat commented Jan 11, 2018

Yes.

@Pilchie
Copy link
Member Author

Pilchie commented Jan 11, 2018

Updated to use Microsoft.CodeAnalysis.PooledObjects

@@ -20,6 +20,7 @@

<PackageReference Include="NuGet.SolutionRestoreManager.Interop" Version="$(NuGetSolutionRestoreManagerInteropVersion)" />
<PackageReference Include="NuGet.VisualStudio" Version="$(NuGetVisualStudioVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.PooledObjects" Version="$(MicrosoftCodeAnalysisPooledObjectsVersion)" />
Copy link
Contributor

Choose a reason for hiding this comment

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

@tmat does this get pulled into the vsix automatically via repotoolset?

Copy link
Member

Choose a reason for hiding this comment

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

It's a source package - the sources are included into the project. No new binary dependencies are added.

@@ -67,6 +67,7 @@
<!-- Roslyn -->
<MicrosoftVisualStudioLanguageServicesVersion>2.6.0-beta1-62113-02</MicrosoftVisualStudioLanguageServicesVersion>
<MicrosoftVisualStudioIntegrationTestUtilitiesVersion>2.6.0-beta1-62113-02</MicrosoftVisualStudioIntegrationTestUtilitiesVersion>
<MicrosoftCodeAnalysisPooledObjectsVersion>2.6.0-beta1-62113-02</MicrosoftCodeAnalysisPooledObjectsVersion>
Copy link
Member

Choose a reason for hiding this comment

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

Could you use a newer version? This version does not have source link support, which might result in build failures.
2.7.0-beta3-62506-01 should be good (even newer ones require some toolset update that's not ready yet).

Copy link
Member

Choose a reason for hiding this comment

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

I'll have a new RepoToolset built in a moment that supports the latest compiler source packages.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I was just trying to match the version of the rest of the Roslyn packages, but I can update this one with a comment about why it is different. So I should pick the latest 2.7 package, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated, but I'm seeing a new error on my work machine that I wasn't seeing at home:

ProjectSystem\VS\Tree\Dependencies\Snapshot\Dependency.cs(337,23): error CS0122: 'PooledStringBuilder' is inaccessible due to its protection level [C:\Code\project-system\src\Microsoft.VisualStudio.ProjectSystem.Managed.VS\mvsokklc.tmp_proj]

Looks like the xaml tmp_proj isn't getting the files added to it. Any ideas?

Copy link
Member

Choose a reason for hiding this comment

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

Odd. Not sure how much the XAML project differs from regular project. My guess would be that nuget can't determine what language it is from the extension and thus doesn't know what language to pick from the source package content types. Perhaps forcing <Language>C#</Language> in Directory.Build.props file next to the project might work?

Copy link
Member Author

Choose a reason for hiding this comment

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

@rrelyea or @jaredpar - do you have any advice here?

@Pilchie
Copy link
Member Author

Pilchie commented Jan 12, 2018

Closing and re-opening to get CI to run.

@Pilchie Pilchie closed this Jan 12, 2018
@Pilchie Pilchie reopened this Jan 12, 2018
@abpiskunov
Copy link
Contributor

FYI, i just ran a small experiment https://gist.github.com/abpiskunov/ba0900a9b38eba27c33e26b6d48d6b85 and string.Join clearly wins vs StringBuilder for small number of strings....

@abpiskunov
Copy link
Contributor

Actually never mind, i did not do restart on stopwatch :( and had intervals instead of separate time chunks. StringBuilder is still better than Join, though they are close in case of small sets of strings.

@Pilchie
Copy link
Member Author

Pilchie commented Jan 17, 2018

Bumping to a top level comment. I can't build this because I get:

ProjectSystem\VS\Tree\Dependencies\Snapshot\Dependency.cs(337,23): error CS0122: 'PooledStringBuilder' is inaccessible
due to its protection level [C:\Code\project-system\src\Microsoft.VisualStudio.ProjectSystem.Managed.VS\pzb2kyvz.tmp_pr
oj]

Note the .tmp_proj. Any idea how to fix this? @rrelyea @jaredpar ? @tmat's suggestion of a Directory.Build.props with <Language>C#</Language> didn't help.

@Pilchie
Copy link
Member Author

Pilchie commented Jan 17, 2018

Also @nguerrera and also @onovotny, since I heard Sdk.Extras might have had to deal with this.

@clairernovotny
Copy link
Member

@Pilchie This may help. There's a workaround in there:
NuGet/Home#5894 (comment)

@Pilchie Pilchie force-pushed the Fix2918-Dependency.GetID branch 2 times, most recently from 41e54db to 2b73f3b Compare January 17, 2018 18:28
@Pilchie
Copy link
Member Author

Pilchie commented Jan 17, 2018

Okay, pushed a couple more commits. Please take another look.

@@ -70,6 +70,9 @@
<RoslynIntegrationVsixVersion>2.6.0.6211302</RoslynIntegrationVsixVersion>
<MicrosoftNetRoslynDiagnosticsVersion>2.6.0-beta1-62322-01</MicrosoftNetRoslynDiagnosticsVersion>

<!-- From roslyn, but source package, so okay for version to mismatch the above -->
<MicrosoftCodeAnalysisPooledObjectsVersion> 2.7.0-beta3-62511-04</MicrosoftCodeAnalysisPooledObjectsVersion>
Copy link
Member

Choose a reason for hiding this comment

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

nit: 2 blank spaces here in value.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed. Actually a TAB!!!

break;
}

return builder;
Copy link
Member

Choose a reason for hiding this comment

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

This return seems wrong. It unconditionally returns from function the first time a value in trimChars is not the end of the build.r

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, those are the semantics of TrimEnd - remove characters from the end of the string that are one of trimChars.

Copy link
Member

@jaredpar jaredpar Jan 17, 2018

Choose a reason for hiding this comment

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

Consider "hello".TrimEnd("zo"). That produces "hell". Your change though will produce "hello" because you unconditionally return after z doesn't match o.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep. Thanks, I thought I had that, but clearly not.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added an explicit check for a match.

@Pilchie Pilchie force-pushed the Fix2918-Dependency.GetID branch from 2b73f3b to d70ecd7 Compare January 17, 2018 18:54
Traces showed this taking upward of 1% of allocations of opening a solution.

Fixes dotnet#2918.
@Pilchie Pilchie force-pushed the Fix2918-Dependency.GetID branch from d70ecd7 to 59961f4 Compare January 17, 2018 18:59
@Pilchie
Copy link
Member Author

Pilchie commented Jan 17, 2018

And fixed my broken rebase :(

@Pilchie
Copy link
Member Author

Pilchie commented Jan 17, 2018

@jaredpar @tmat - does repo toolset control compiler version?

vbc : error BC2014: the value '15.5' is invalid for option 'langversion' [D:\j\workspace\windows_relea---15bd572b\src\Microsoft.VisualStudio.Editors\vtztzpdf.tmp_proj]

@Pilchie
Copy link
Member Author

Pilchie commented Jan 17, 2018

Or, that being the tmp_proj again, are we not using the toolset compiler for it?

@jaredpar
Copy link
Member

@Pilchie that error is on the WPF temp project file and you're setting the VB language version in a section for VB only. Guessing it's that issue.

@Pilchie
Copy link
Member Author

Pilchie commented Jan 17, 2018

"that issue" is usually that the project doesn't know what language it is, but in this case, it knew to apply the VB setting, so instead it sounds like it's failing to apply the toolset compiler. Any idea how to workaround? In the meantime, I think I just won't specify langver for VB.

@jaredpar
Copy link
Member

@Pilchie ah I see. That error does'nt make a lot of sense. Will wait for @tmat to comment on how the compiler toolset is chosen. That is likely the issue here.

@Pilchie
Copy link
Member Author

Pilchie commented Jan 17, 2018

Now I seem to be getting a compiler crash in C# :(

 Unhandled Exception: System.ArgumentException: Illegal characters in path.
    at System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)
    at System.IO.Path.GetFileName(String path)
    at Microsoft.CodeAnalysis.Compilation.SerializeToPeStream(CommonPEModuleBuilder moduleBeingBuilt, EmitStreamProvider peStreamProvider, EmitStreamProvider metadataPEStreamProvider, EmitStreamProvider pdbStreamProvider, Func`1 testSymWriterFactory, DiagnosticBag diagnostics, Boolean metadataOnly, Boolean includePrivateMembers, Boolean emitTestCoverageData, String pePdbFilePath, CancellationToken cancellationToken)
    at Microsoft.CodeAnalysis.CommonCompiler.RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken)
    at Microsoft.CodeAnalysis.CommonCompiler.Run(TextWriter consoleOutput, CancellationToken cancellationToken)
    at Microsoft.CodeAnalysis.CSharp.CommandLine.Csc.<>c__DisplayClass1_0.<Run>b__0(TextWriter tw)
    at Microsoft.CodeAnalysis.CommandLine.ConsoleUtil.RunWithUtf8Output[T](Func`2 func)
    at Microsoft.CodeAnalysis.CSharp.CommandLine.Csc.Run(String[] args, BuildPaths buildPaths, TextWriter textWriter, IAnalyzerAssemblyLoader analyzerLoader)
    at Microsoft.CodeAnalysis.CommandLine.DesktopBuildClient.RunLocalCompilation(String[] arguments, BuildPaths buildPaths, TextWriter textWriter)
    at Microsoft.CodeAnalysis.CommandLine.BuildClient.RunCompilation(IEnumerable`1 originalArguments, BuildPaths buildPaths, TextWriter textWriter)
    at Microsoft.CodeAnalysis.CommandLine.DesktopBuildClient.Run(IEnumerable`1 arguments, RequestLanguage language, CompileFunc compileFunc, IAnalyzerAssemblyLoader analyzerAssemblyLoader)
    at Microsoft.CodeAnalysis.CSharp.CommandLine.Program.Main(String[] args)

@tmat
Copy link
Member

tmat commented Jan 17, 2018

Re compiler versions used:
The default version is currently 2.7.0-beta2-62330-02: https://github.com/dotnet/roslyn-tools/blob/master/sdks/RepoToolset/tools/DefaultVersions.props#L29
Repo can override it by specifying the value of <MicrosoftNetCompilersVersion> property in Versions.props file.

As for the compiler crash ... looking into the log now: https://ci.dot.net/job/dotnet_project-system/job/dev15.6.x/job/windows_debug_prtest/12/artifact/artifacts/debug/log/ ...

@tmat
Copy link
Member

tmat commented Jan 17, 2018

I see no obvious issue :(

@Pilchie
Copy link
Member Author

Pilchie commented Jan 17, 2018

We appear to set MicrosoftNetCompilersVersion to 2.6.0-beta3-62310-01 here.

Maybe worth updating?

@tmat
Copy link
Member

tmat commented Jan 17, 2018

@Pilchie Definitely. I'd just remove it so that it defaults to the one defined in RepoToolset.

@Pilchie
Copy link
Member Author

Pilchie commented Jan 17, 2018

No joy:

C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\MSBuild\15.0\Bin\Roslyn\Microsoft.
VisualBasic.Core.targets(87,10): error MSB4064: The "EmbedAllSources" parameter is not supported by
the "Vbc" task. Verify the parameter exists on the task, and it is a settable public instance proper
ty. [C:\Code\project-system\src\Microsoft.VisualStudio.Editors\aaodp2bk.tmp_proj]
C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\MSBuild\15.0\Bin\Roslyn\Microsoft.
VisualBasic.Core.targets(73,5): error MSB4063: The "Vbc" task could not be initialized with its inpu
t parameters.  [C:\Code\project-system\src\Microsoft.VisualStudio.Editors\aaodp2bk.tmp_proj]

@Pilchie Pilchie force-pushed the Fix2918-Dependency.GetID branch from 94e4ec1 to 4666ca2 Compare January 22, 2018 23:52
@Pilchie
Copy link
Member Author

Pilchie commented Jan 22, 2018

Reverted to just using a local pool for 15.6. @tmat @jaredpar any objectsions?

@jaredpar
Copy link
Member

SGTM

@Pilchie Pilchie merged commit 96e1792 into dotnet:dev15.6.x Jan 23, 2018
@Pilchie Pilchie deleted the Fix2918-Dependency.GetID branch January 23, 2018 00:28
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