Dot-Net

自編譯 Roslyn 建構性能:不如最初發布的 Roslyn 版本快

  • January 23, 2016

我在做什麼用一句話

Update-1Roslyn github 儲存庫中檢查分支,建構 csc.exe,並使用我自己建構的 csc.exe 版本編譯隨機解決方案。

預期結果

我希望性能與 VS 2015 Update 1 附帶的原始 Roslyn 版本相當,位於路徑中:C:\Program Files (x86)\MSBuild\14.0\Bin

實際結果

與原始版本相比,我自己建構的 Roslyn 版本的建構性能要差得多。在我在測試中使用的解決方案中:大約 30 秒對 65 秒。

我的程序更詳細

  • 複製https://github.com/dotnet/roslyn.git並簽出分支 update-1
  • 使用配置建構 Roslyn Release(嘗試了兩者Mixed Configuration以及x64解決方案平台。)
  • 為了編譯測試解決方案,我更改了所有項目文件以使用 csc 路徑的特定位置:

<CscToolPath>C:\Path\To\Output\Location\Of\Roslyn\Binaries\</CscToolPath>

  • 出於測試目的,我正在從命令行建構測試解決方案

MSBuild.exe /t:Rebuild /m:1 /verbosity:m MySolutionName.sln

  • 我目前也在做清潔工作:

MSBuild.exe /t:Clean /m:1 /verbosity:m MySolutionName.sln

  • 為了針對 VS 2015 Update 1 附帶的原始編譯器進行測試,我將項目文件中的配置更改為:

<CscToolPath>C:\Program Files (x86)\MSBuild\14.0\Bin\</CscToolPath>

問題

  • 我可以做些什麼來實現與我的自編譯 Roslyn 版本類似的性能,就像最初發布的 Roslyn dll 一樣?
  • 在建構 Roslyn 本身時,是否還有其他需要考慮的事情(如優化等)?

最大的不同是,Visual Studio 安裝的官方編譯器在 NGEN 中編譯為安裝的一部分。

但是,即使您使用 NGEN,也不會得到完全相同的結果,因為 Microsoft 提供了支持部分 NGEN 的配置文件引導訓練數據,以便在二進制大小和不屬於公共 repo 的 JIT 時間之間取得良好的平衡(類似於使用 Microsoft 官方私鑰進行簽名)。

除了完全正確的 Kevin 回答之外,這裡還有一些關於簽名/NGEN 編譯 Roslyn 二進製文件的更多細節,因為這對其他人來說可能很有趣。

  • 為了 NGEN 編譯二進製文件,它們必須有一個強名稱,這意味著它們必須被簽名
  • 通常,Roslyn 二進製文件是使用 Microsoft 私鑰延遲簽名的,正如 Kevin 還指出的那樣。
  • 所以我們必須使用我們自己的密鑰對進行簽名
  • 相應的配置可以在 Roslyn repo 的build\Targets\VSL.Imports.targets文件中找到
  • 出於測試目的,我們可以替換此部分:
<Choose>
   <When Condition="'$(SignAssembly)' == 'true'">
     <Choose>
       <!-- Shipping binaries in an "official" build are delay-signed with the MS key; later, the signing
            system will finish the strong-name signing. -->
       <When Condition="'$(NonShipping)' != 'true'">
         <PropertyGroup>
           <AssemblyOriginatorKeyFile>$(VSLToolsPath)\Strong Name Keys\35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
           <DelaySign>true</DelaySign>
           <PublicKey>0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9</PublicKey>
           <PublicKeyToken>31BF3856AD364E35</PublicKeyToken>
         </PropertyGroup>
       </When>

       <!-- Non-shipping binaries are simply signed with the Roslyn internal key. -->
       <Otherwise>
         <PropertyGroup>
           <AssemblyOriginatorKeyFile>$(VSLToolsPath)\Strong Name Keys\RoslynInternalKey.Private.snk</AssemblyOriginatorKeyFile>
           <DelaySign>false</DelaySign>
           <PublicKey>$(RoslynInternalKey)</PublicKey>
           <PublicKeyToken>fc793a00266884fb</PublicKeyToken>
         </PropertyGroup>
       </Otherwise>
     </Choose>
   </When>
</Choose>

例如,這個:

<Choose>  
<When Condition="'$(SignAssembly)' == 'true'">
 <PropertyGroup>
   <AssemblyOriginatorKeyFile>C:\path\to\keyfile\TestKey.snk</AssemblyOriginatorKeyFile>
   <DelaySign>false</DelaySign>
   <PublicKey>0024000004800000940000000602000000240000525341310004000001000100B15B00E697DB995031A740A3E07A0B1DBE16AAEA61E615A013E0381B4D875F97F1792965D58810893F6D4B1C10CBD991FB8E9F1118D9C0C6F0EBCB50462FC25056E194667CB59822C18E9CB0C17DBC573291F05F7C87B51C48B377C9EEE12F6D5B331B235E5D6E3669737B210F7BE245A76B118C23EAD90FC392E4ED9F6CDFAB/PublicKey>
   <PublicKeyToken>6E0B9EF75D28854E</PublicKeyToken>
 </PropertyGroup>
</When>
</Choose>
  • …使用您自己的密鑰文件、公鑰以及公鑰令牌。
  • 可以在 Visual Studio 中或借助sn.exe工具創建密鑰文件。
  • sn.exe也可用於導出公鑰以及提取公鑰令牌(例如,從您可以使用密鑰測試簽名的程序集中)
  • 那麼NGEN可以這樣呼叫:

ngen.exe install "C:\path\to\Roslyn\Release\csc.exe"

(例如位於C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe

引用自:https://stackoverflow.com/questions/34853273