Home Dashboard Directory Help
Search

Severe performance decrease when generating many types into an AssemblyBuilder by xtoff_


Status: 

Closed
 as Fixed Help for as Fixed


27
0
Sign in
to vote
Type: Bug
ID: 472622
Opened: 7/5/2009 1:46:55 AM
Access Restriction: Public
1
Workaround(s)
view
21
User(s) can reproduce this bug

Description

When creating a dynamic assembly (using System.Reflection.Emit.AssemblyBuilder) and creating multiple types in this assembly it has been observed that time to create a new type rises exponentially with the number of the types. Profiling showed that all the performance decrease is happening in System.Reflection.Emit.AssemblyBuilderData.CheckTypeNameConflict(string strTypeName, TypeBuilder enclosingType)

You can see this issue in Castle Dynamic Proxy issue tracker, and use attached program that exposes the issue:
http://support.castleproject.org/projects/DYNPROXY/issues/view/DYNPROXY-ISSUE-98
Details
Sign in to post a comment.
Posted by Microsoft on 3/24/2010 at 10:11 AM
Hello,

I apologize for the confusion in the resolution state. As I mentioned earlier, we could not make this change to .NET 4 due to where we were (and are) in the product cycle - this item was actually fixed for the next version of the CLR (hence the resolution).

Again, sorry for the confusion.

Thank you,
Andrew
Posted by Firestrand on 3/24/2010 at 9:55 AM
This is still a problem in .NET 4.0 RC when I tested.
Posted by Microsoft on 7/14/2009 at 11:46 AM
Thank you for submitting your feedback to Microsoft. The current .NET implementation loops through all existing types to check for name conflicts when a new type is defined in a dynamic assembly. This makes the running time of creating a new type proportional to the number of types already defined in the dynamic assembly.

While this is certainly something we can look into improving, we likely won’t be able to address this in the .NET Framework 4 release, as the bar for bugs is extremely high due to where we are in the release cycle (close to Release Candidate). We will track this as something to investigate for a future .NET Framework release.

Thank you,
Andrew Dai
Microsoft Corp. – Common Language Runtime
Posted by Microsoft on 7/6/2009 at 1:45 AM
Thank you for your feedback, We are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
Posted by Firestrand on 3/26/2010 at 7:12 AM
Here is a work around:

After you create a Type in a dynamic assembly call the extension method Type.RemoveTypeBuilder.
WARNING: The TypeBuilder List on the Type.Module (a ModuleBuilder instance) is used to check and prevent Type name conflicts in a dynamic assembly. You must keep a HashSet or in some way ensure you don't get a name conflict if you clear the TypeBuilder list using the code below. Also this is not "optimal" code in that there are ways to speed up reflection. So far this is working without a problem for me but your mileage may vary.


        public static void ClearTypeBuilderList(this ModuleBuilder modBuild)
        {
            if (modBuild == null)
                return;
            Type modBuildType = typeof(ModuleBuilder);
            FieldInfo modTypeBuildList = modBuildType.GetField("m__TypeBuilderList", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
            ArrayList modTypeList = modTypeBuildList.GetValue(modBuild) as ArrayList;
            if (modTypeList != null)
                modTypeList.Clear();
        }
        public static void RemoveTypeBuilder(this Type type)
        {
            ModuleBuilder modBuild = type.Module as ModuleBuilder;
            modBuild.ClearTypeBuilderList();
        }