exceptions performance (Re: [Mono-devel-list] JIT profiling/benchmarking)

Michal Moskal malekith at pld-linux.org
Sat Jan 3 19:29:39 EST 2004


On Sat, Jan 03, 2004 at 11:37:29PM +0100, Paolo Molaro wrote:
> > I also heard about delegates being 20x slower when invoking and creating
> > then creating objects and invoking methods (*). But that was about .NET 1.0 (or
> 
> Care to create a little benchmark with the two different ways to do it?
> I'm not sure what kind of usage you mean exactly, but creating a
> delegate is slightly more time consuming than creating a simple object
> and so it a delegate call vs a simple method (interface) call, but the
> overhead should be much lower than 20x.
> In my tests calls through a delegate are 2-2.5x (for an empty method)
> slower than interface calls. I didn't measure delegate creating time,
> though: again, you might want to write a benchmark that does what you
> want and post it to the list, so we can run it and see if we can make
> improvements to the run time.

Ok, first chunk of benchmarks.

I tested delegate vs interface approach. Delegate call time seems to be
somewhat slower then method call, but still acceptable (as you said).

However delegate creation is about 10 times slower then equivalent object
creation (you can observe this by setting call_cnt to 0 and tweaking if
(true) around line 157 of delegate-nobox.cs).

My common case seems to be few calls to delegate after creation (say
10), so while the call overheads are rather small, the creation overhead
seems big.

-- 
: Michal Moskal :: http://www.kernel.pl/~malekith : GCS {C,UL}++++$ a? !tv
: When in doubt, use brute force. -- Ken Thompson : {E-,w}-- {b++,e}>+++ h
-------------- next part --------------
delegate int F0 ();
delegate int F1 (int a1);
delegate int F2 (int a1, int a2);

interface I0 {
	int apply ();
}

interface I1 {
	int apply (int a1);
}

interface I2 {
	int apply (int a1, int a2);
}

class InterfaceTest {
	public class Closure {
		public int acc;
	}

	public class f0 : I0 {
		Closure clo;
		public f0 (Closure c) { clo = c; }
		public int apply()
		{
			return clo.acc++;
		}
	}
	public class f1 : I1 {
		Closure clo;
		public f1 (Closure c) { clo = c; }
		public int apply(int x)
		{ 
			return clo.acc += (int)x;
		}
	}
	public class f2 : I2 {
		Closure clo;
		public f2 (Closure c) { clo = c; }
		public int apply(int x, int y)
		{ 
			return clo.acc += (int)x + (int)y;
		}
	}
}

class DelegateTest {
	int acc;

	int f0 ()
	{
		return acc++;
	}

	int f1 (int x)
	{
		return acc += (int) x;
	}
	
	int f2 (int x, int y)
	{
		return acc += (int) x + (int) y;
	}

	public F0 make_f0 ()
	{
		return new F0(f0);
	}

	public F1 make_f1 ()
	{ 
		return new F1(f1);
	}
	
	public F2 make_f2 ()
	{
		return new F2(f2);
	}
}

class MainClass {
	public const int call_cnt = 10;
	
	static int run_F0 (F0 f)
	{
		int sum = 0;
		for (int i = 0; i < call_cnt; i++)
			sum += (int)f();
		return sum;
	}
	static int run_F1 (F1 f)
	{
		int sum = 0;
		for (int i = 0; i < call_cnt; i++)
			sum += (int)f(i);
		return sum;
	}
	static int run_F2 (F2 f)
	{
		int sum = 0;
		for (int i = 0; i < call_cnt; i++)
			sum += (int)f(i, i);
		return sum;
	}

	static int delegate_test ()
	{
		DelegateTest t = new DelegateTest ();
		int ret = 0;
		
		ret += run_F0 (t.make_f0 ());
		ret += run_F1 (t.make_f1 ());
		ret += run_F2 (t.make_f2 ());

		return ret;
	}

	static int run_I0 (I0 f)
	{
		int sum = 0;
		for (int i = 0; i < call_cnt; i++)
			sum += (int)f.apply();
		return sum;
	}
	static int run_I1 (I1 f)
	{
		int sum = 0;
		for (int i = 0; i < call_cnt; i++)
			sum += (int)f.apply(i);
		return sum;
	}
	static int run_I2 (I2 f)
	{
		int sum = 0;
		for (int i = 0; i < call_cnt; i++)
			sum += (int)f.apply(i, i);
		return sum;
	}

	static int iface_test ()
	{
		InterfaceTest.Closure clo = new InterfaceTest.Closure ();
		int ret = 0;
		
		ret += run_I0 (new InterfaceTest.f0 (clo));
		ret += run_I1 (new InterfaceTest.f1 (clo));
		ret += run_I2 (new InterfaceTest.f2 (clo));

		return ret;
	}

	public static void Main ()
	{
		int ret = 0;

		if (!true)
			for (int i = 0; i < 1000000; i++)
				ret += iface_test ();
		else
			for (int i = 0; i < 1000000; i++)
				ret += delegate_test ();
		
		System.Console.WriteLine (ret);
	}
}


More information about the Mono-devel-list mailing list