2

私の Buildprocess は正常に動作しますが、非常に小さなプロジェクトでは 3 秒近くかかります。

ビルドプロセスをスピードアップするにはどうすればよいですか?

ログファイルは投稿するには大きすぎます。ロガーの出力についてお気軽に質問してください。リクエストされた部分を投稿します。

プロジェクトをビルドする C# メソッド

private void CompileCode()
        {
            using (var buildManager = new BuildManager())
            {
                var result = buildManager.Build(this.CreateBuildParameters(), this.CreateBuildRequest());

                if (result.OverallResult == BuildResultCode.Failure)
                {
                    // Error handling
                    var stringbuilder = new StringBuilder();

                    using (var reader = new StreamReader(NameDebuggerLogFile))
                    {
                        stringbuilder.Append(reader.ReadToEnd());
                    }

                    throw new CompilerException(stringbuilder.ToString());
                }
            }
        }

        private BuildParameters CreateBuildParameters()
        {
            var projectCollection = new ProjectCollection();
            var buildLogger = new FileLogger { Verbosity = LoggerVerbosity.Detailed, Parameters = "logfile=" + NameDebuggerLogFile };
            var buildParameters = new BuildParameters(projectCollection) { Loggers = new List<ILogger>() { buildLogger } };
            return buildParameters;
        }

        private BuildRequestData CreateBuildRequest()
        {
            var globalProperties = new Dictionary<string, string>();
            var buildRequest = new BuildRequestData(FolderPath + NameProjectFile, globalProperties, null, new[] { "Build" }, null, BuildRequestDataFlags.ReplaceExistingProjectInstance);
            return buildRequest;
        }

ビルド プロセスに使用されるプロジェクト ファイル

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <AssemblyName>GeneratedFlexForm</AssemblyName>
    <OutputPath>DLL</OutputPath>
    <OutputType>Library</OutputType>
    <DebugType>none</DebugType>
    <DebugSymbols>false</DebugSymbols>
    <Optimize>false</Optimize>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.ServiceModel" />
    <Reference Include="System.Runtime.Serialization" />
    <Reference Include="System.Web" />
    <Reference Include="System.Web.Services" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Design" />
    <Reference Include="System.Data" />
    <Reference Include="System.Core" />
    <Reference Include="System.Management" />
    <Reference Include="System.Configuration" />
    <Reference Include="System.Xaml">
      <RequiredTargetFramework>4.0</RequiredTargetFramework>
    </Reference>
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
    <!--<Reference Include="FlexForms.Core" />-->
    <Reference Include="FlexForms.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>Library\FlexForms.Core.dll</HintPath>
    </Reference>
    <Reference Include="Gizmox.WebGUI.Forms">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>Library\Gizmox.WebGUI.Forms.dll</HintPath>
    </Reference>
    <Reference Include="Gizmox.WebGUI.Common">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>Library\Gizmox.WebGUI.Common.dll</HintPath>
    </Reference>
    <Reference Include="FlexForms.ServiceProviders">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>Library\FlexForms.ServiceProviders.dll</HintPath>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Page Include="FlexForm.xaml">
      <Generator>MSBuild:Compile</Generator>
      <DependentUpon>RadioButtonValueConverter.cs</DependentUpon>
      <SubType>Designer</SubType>
    </Page>
    <Compile Include="FlexForm.xaml.cs">
      <DependentUpon>FlexForm.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="UserCode.cs">
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="RadioButtonValueConverter.cs">
      <SubType>Code</SubType>
    </Compile>
    <Resource Include="datacontext.xml"/>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

ビルド中に収集されたロガー出力(ファイル サイズのため、最後の行のみ)

プロジェクト「projectfile.csproj」のビルドが完了しました。

ビルドが成功しました。0 警告 0 エラー

経過時間 00:00:02.68

編集:

ここでセヴァ・ティトフの言葉を引用させていただければ幸いです。

たとえば、XAML ファイルは 2 回再コンパイルされます (MSDN を参照)。csc.exe だけでは簡単に複製できません。プロジェクトに XAML がある場合は、MSBuild を使用する必要があります。– セヴァ・ティトフ

そのため、MSBuild に固執する必要があります。

とにかく、パフォーマンスを改善するためのいくつかのアイデアがありました。

問題 1: これは私のログファイルからのスニペットであり、MSBuild が依存関係を解決している間に .winmd、.dll、および .exe ファイルを処理することを示しています。

AllowedAssemblyExtensions:
    .winmd
    .dll
    .exe

私は.dllファイルしか持っていないので、MSBuildが.winmdファイルを考慮することを無効にしたいと思います。これは、私の依存関係のほぼすべてに当てはまります。(下の例)

プライマリ リファレンス「PresentationCore、Version=4.0.0.0、Culture=neutral、PublicKeyToken=31bf3856ad364e35」。解決されたファイル パスは、「C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\PresentationCore.dll」です。検索パスの場所「{TargetFrameworkDirectory}」で参照が見つかりました。SearchPath "{TargetFrameworkDirectory}" の場合。「C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\PresentationCore.winmd」を検討しましたが、存在しませんでした。

解決策: 1 CreateBuildRequest() メソッドを変更する必要がありました。

private BuildRequestData CreateBuildRequest()
{
    var globalProperties = new Dictionary<string, string>();
    // Related to idea 1           
    globalProperties.Add("ExpandSDKAllowedReferenceExtensions", ".dll");
    globalProperties.Add("AllowedReferenceAssemblyFileExtensions", ".dll");
    globalProperties.Add("AllowedReferenceRelatedFileExtensions", string.Empty);
    // Related to idea 2     
    globalProperties.Add("BuildProjectReferences", "false");
    globalProperties.Add("BuildInParallel", "true");
    var buildRequest = new BuildRequestData(FolderPath + NameProjectFile, globalProperties, "4.0", new[] { "Build" }, null, BuildRequestDataFlags.IgnoreExistingProjectState);
    return buildRequest;
}

EDIT2: アイデア 2: プロジェクトを並行してビルドするために /maxcpucount または /m スイッチを含める方法を知っている人はいますか? このMSDNページで説明されていますが、上記のプロジェクトファイルに適用する方法がわかりません

解決策 2:解決策 1 を参照してください。ただし、あまり変わりませんでした。

EDIT3: 何時間も遊んだ後、あきらめなければならないと思います。私が見る唯一のオプションは、一般的に依存関係を減らすことです。しかし、これについては後で戻ってきます。

少し無関係:

> Task Performance Summary:
>         0 ms  CreateItem                                 1 calls
>         0 ms  AssignCulture                              1 calls
>         0 ms  CallTarget                                 2 calls
>         0 ms  FindAppConfigFile                          1 calls
>         0 ms  Delete                                     4 calls
>         0 ms  GetFrameworkPath                           1 calls
>         0 ms  ConvertToAbsolutePath                      1 calls
>         0 ms  MakeDir                                    1 calls
>         0 ms  Message                                    5 calls
>         0 ms  AssignTargetPath                           6 calls
>         1 ms  FindUnderPath                              5 calls
>         1 ms  FileClassifier                             1 calls
>         1 ms  RemoveDuplicates                           2 calls
>         1 ms  CreateCSharpManifestResourceName           1 calls
>         1 ms  ReadLinesFromFile                          1 calls
>        15 ms  ResolveAssemblyReference                   1 calls
>        21 ms  ResourcesGenerator                         1 calls
>        56 ms  Copy                                       2 calls
>       299 ms  GenerateTemporaryTargetAssembly            1 calls
>       502 ms  Csc                                        2 calls
>       725 ms  MarkupCompilePass1                         1 calls
>       814 ms  MarkupCompilePass2                         1 calls
> 
> Build succeeded.
>     0 Warning(s)
>     0 Error(s)
> 
> Time Elapsed 00:00:02.27
4

2 に答える 2

6

あなたの直接の質問に答えるために、msbuild を高速化するためにできることはあまりありません。お使いのマシンで SSD を使用していれば、より高速に実行されると思いますが、それはおそらくあなたが探している種類のソリューションではありません。

他に考えられる唯一のことは、msbuild の使用を完全に停止することです。C# コンパイラを駆動するだけです。では、なぜ msbuild を気にする必要があるのでしょうか。C# コンパイラを直接使用するだけです。たとえば、経由でCSharpCodeProvider

于 2013-03-27T12:29:34.323 に答える
-1

私が提案できる簡単な方法の 1 つは、次のコマンドのように MSBuild プロパティを指定して、プロセッサの複数のコアを利用することです。

msbuild default.msbuild /m:1

/m属性が内部でどのように有効になるかはわかりません。

編集:

私が見た限り、スレッドはプロジェクトの外部で発生します。ソリューション内の複数のプロジェクトは、プロジェクトごとに 1 つのスレッドで並行して実行されます。そのため、これをプロジェクト オプションとして追加できない場合があります。

しかし、別のHanselman リンクで、これを Visual Studio に組み込み、ソリューションのコンパイルと一緒に実行するためのハックを見つけました。これをチェックしてください。

ここでは、MSBuild を外部ツールとして追加して、この属性でソリューションを実行します。

于 2013-03-28T09:43:57.307 に答える