Title: Performance issues with Solution task

Hi,

We have hit some fairly significant performance problems with the solution task. The performance problems all seem to be centered on:

NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences() and

NAnt.VSNet.ProjectBase.GetAssemblyReferences()

(These two methods call each other recursively.)

The performance problem shows up in two locations:

  1. In VB projects there is code to recursively call these for each resource file for each assembly

  2. In the call to the compiler, these methods are called to trace the reference structure

To give you an example, we had a build of about 50 DLLs that took about 45 minutes. When we added another 5 EXEs to the build, the build time jumped by about an hour not because of added compile time, but because of all the time spent recursively checking references. (When I ran a profiler, I think 80% of the time was spend in File.Exists().)

I would really like to get these issues resolved. I am willing to jump into the code and attempt the fix, but I am sure someone else is a lot more familiar with these classes and methods.

If there is anything I can expand on, please let me know.

Thanks,

Don

Ive attached some more specifics.

<<performance issue in resource generation - for VB projects>>

==============================================================================
This communication, together with any attachments hereto or links contained herein, is for the sole use of the intended recipient(s) and may contain information that is confidential or legally protected. If you are not the intended recipient, you are hereby notified that any review, disclosure, copying, dissemination, distribution or use of this communication is STRICTLY PROHIBITED. If you have received this communication in error, please notify the sender immediately by return e-mail message and delete the original and all copies of the communication, along with any attachments hereto or links herein, from your system.

==============================================================================
The St. Paul Travelers e-mail system made this annotation on 08/02/05, 14:22:24.

--- Begin Message ---
Title: performance issue in resource generation - for VB projects

I think I have discovered a performance issue with resource generation on large builds – it is VB specific.

Long story short: For each resource file in a project, the entire reference structure of your project is traversed and every referenced project is traversed, repeat recursively.

Basically: The Resource class, in the CompileResx method, creates a ResGenTask then iterates through each reference and adds dependent assemblies to the ResGenTask:

Resource.cs (line 357)

foreach (ReferenceBase reference in Project.References) {

    StringCollection assemblyReferences = reference.GetAssemblyReferences(

        solutionConfiguration);

    foreach (string assemblyFile in assemblyReferences) {

        rt.Assemblies.Includes.Add(assemblyFile);

    }

}

ProjectReferenceBase.GetAssemblyReferences() calls  ProjectBase.GetAssemblyReferences() – but only for VB projects:

ProjectReferenceBase.cs (line 146)

// check if parent is a VB.NET project

if (typeof(VBProject).IsAssignableFrom(Parent.GetType())) {

    assemblyReferences = Project.GetAssemblyReferences(solutionConfiguration);

} else {

    assemblyReferences = new StringCollection();

}

ProjectBase.GetAssemblyReferences() loops through each reference and calls ProjectReferenceBase.GetAssemblyReferences()

ProjectBase.cs (line 335)

foreach (ReferenceBase reference in References) {

    StringCollection references = reference.GetAssemblyReferences(solutionConfiguration);

    ...

Here is a sample stack trace:

>       nant.vsnettasks.dll!NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 158 + 0x8 bytes  C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 336 + 0xb bytes   C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 148 + 0x15 bytes C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 336 + 0xb bytes   C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 148 + 0x15 bytes C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 336 + 0xb bytes   C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 148 + 0x15 bytes C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 336 + 0xb bytes   C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 148 + 0x15 bytes C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 336 + 0xb bytes   C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 148 + 0x15 bytes C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 336 + 0xb bytes   C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 148 + 0x15 bytes C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 336 + 0xb bytes   C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 148 + 0x15 bytes C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 336 + 0xb bytes   C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 148 + 0x15 bytes C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 336 + 0xb bytes   C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectReferenceBase.GetAssemblyReferences(string solutionConfiguration = "debug") Line 148 + 0x15 bytes C#

        nant.vsnettasks.dll!NAnt.VSNet.Resource.CompileResx(string solutionConfiguration = "debug") Line 358 + 0xb bytes        C#

        nant.vsnettasks.dll!NAnt.VSNet.Resource.Compile(string solutionConfiguration = "debug") Line 113 + 0xa bytes    C#

        nant.vsnettasks.dll!NAnt.VSNet.ManagedProjectBase.WriteCompilerOptions(System.IO.StreamWriter sw = {System.IO.StreamWriter}, string solutionConfiguration = "debug") Line 559 + 0xe bytes       C#

        nant.vsnettasks.dll!NAnt.VSNet.ManagedProjectBase.Build(string solutionConfiguration = "debug") Line 320 + 0x11 bytes   C#

        nant.vsnettasks.dll!NAnt.VSNet.ProjectBase.Compile(string solutionConfiguration = "debug") Line 314 + 0x9 bytes C#

        nant.vsnettasks.dll!NAnt.VSNet.SolutionBase.Compile(string solutionConfiguration = "debug") Line 215 + 0x38 bytes       C#

        nant.vsnettasks.dll!NAnt.VSNet.Tasks.SolutionTask.ExecuteTask() Line 409 + 0x1a bytes   C#

        nant.core.dll!NAnt.Core.Task.Execute() Line 169 + 0x8 bytes     C#

        nant.core.dll!NAnt.Core.Target.Execute() Line 247 + 0xa bytes   C#

        nant.core.dll!NAnt.Core.Project.Execute(string targetName = "minor", bool forceDependencies = false) Line 889   C#

        nant.core.dll!NAnt.Core.Project.Execute() Line 837 + 0x39 bytes C#

        nant.core.dll!NAnt.Core.Project.Run() Line 927  C#

        nant.core.dll!NAnt.Core.ConsoleDriver.Main(string[] args = {Length=0}) Line 167 + 0xb bytes     C#


--- End Message ---

Reply via email to