[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