[Mono-devel-list] [GMCS] [PATCH] helper_compile_generic_method and poor performance
Michal Moskal
michal.moskal at gmail.com
Wed Jul 20 17:48:16 EDT 2005
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)
--
Michal Moskal,
http://nemerle.org/~malekith/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: perf.patch
Type: application/octet-stream
Size: 638 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20050720/14a683b2/attachment.obj
More information about the Mono-devel-list
mailing list