[Mono-devel-list] [GMCS] [PATCH] helper_compile_generic_method and poor performance

Martin Baulig martin at ximian.com
Mon Jul 25 13:17:05 EDT 2005


Hi,

your patch looks good, I'll commit it tomorrow morning.

Martin

On Wed, 2005-07-20 at 23:48 +0200, Michal Moskal wrote:
> Hello,
> 
> I've been further investigating poor mono performance on generic code, reported
> in #75444.  By comparing profiler[1] logs of the generic and non-generic
> compiler I found a method that now takes 20x more time to execute and later
> created a micro benchmark:
> 
> #v+
> class C {
>   public void foo<T> (T t)
>   {
>   }
> 
>   public static void Main ()
>   {
>     for(int i = 0; i < 10000; ++i) {
>           C q = new C();
>           q.foo ("foo");
>     }
>   }
> }
> #v-
> 
> This gives:
> 
> Mono Jit statistics
> Compiled methods:       10040
> 
> (and yes, of you increase the loop counter you'll get more methods compiled).
> This takes lots of time.
> 
> Anyway the problem is that helper_compile_generic_method calls 
> mono_class_inflate_generic_method which doesn't cache the results,
> which in turn means g_hashtable misses in jit_code_hash. 
> 
> Note that this is not about code sharing -- the instances are exactly
> the same, moreover from the same call site.
> 
> Now helper_compile_generic_method is ,,called'' from mono_method_to_ir
> (in mini.c), opcode CEE_CALLVIRT. It is called only for callvirt (not
> for regular call), and only when the method called is generic. I disabled
> it there (so it handled it like non-virt calls), and the compile time
> drop down from 55s to 30s.
> 
> The question is what is it for? I guess this is for the case when a
> generic method is overridden in a derived class. If so maybe the attached
> patch, which enables helper_compile_generic_method only when the method
> is virtual and non-final could be applied? It works for me 
> performance-wise like disabling this altogether.
> 
> I actually wanted to test if I didn't break anything, so I come up with
> a test (I couldn't find anything in tests/gmcs):
> 
> #v+
> class C1 {
>   public virtual int foo<T> ()
>   {
>     return 1;
>   }
> }
> 
> class C2 : C1 {
>   public override int foo<T> ()
>   {
>     return 2;
>   }
> }
> 
> class T {
>   public static int Main ()
>   {
>     	C1 c1 = new C1 ();
>         for (int pass = 1; pass <= 2; ++pass) {
>           if (c1.foo<int>() != pass)
>             return 1;
>           c1 = new C2 ();
>         }
>         return 0;
>   }
> }
> #v-
> 
> However even with unpatched mono it gives:
> 
> ** ERROR **: file object.c: line 1149 (mono_object_get_virtual_method):
> assertion failed: (res)
> 
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list




More information about the Mono-devel-list mailing list