|
#region LGPL License
/*
* DynamicMethod Delegates Demo
*
* Copyright (C) 2005
* Alessandro Febretti <mailto:febret@gmail.com>
* SharpFactory
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#endregion
using System;
using System.Reflection;
using System.Drawing;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace SharpFactory.DMDDemo
{
class TestClass
{
public static float StaticTestMethod(float a, float b)
{
return a + b;
}
public static string StaticTestMethodNoBoxing(string a, string b)
{
return a + b;
}
public virtual string VirtualTestMethod(string name, int i, Color color)
{
string postfix = "";
if (i != 1)
{
postfix = "s";
}
return "I have " + i + " " + color.Name + " " + name + postfix + ".";
}
}
class DerivedTestClass : TestClass
{
public override string VirtualTestMethod(string name, int i, Color color)
{
string postfix = "";
if (i != 1)
{
postfix = "s";
}
return "My " + i + " " + name + postfix +
" aren't really " + color.Name + ".";
}
}
class Program
{
#region Fields
static TestClass _instance;
static DerivedTestClass _derivedInstance;
static MethodInfo _varargsInfo;
static MethodInfo _staticInfo;
static MethodInfo _staticNoBoxingInfo;
static MethodInfo _virtualInfo;
static DynamicMethodDelegate _varargsDMD;
static DynamicMethodDelegate _staticDMD;
static DynamicMethodDelegate _staticNoBoxingDMD;
static DynamicMethodDelegate _virtualDMD;
#endregion
#region Methods
static void Main(string[] args)
{
// Initalize objects used for testing.
_instance = new TestClass();
_derivedInstance = new DerivedTestClass();
_staticInfo = _instance.GetType().GetMethod("StaticTestMethod");
_staticNoBoxingInfo = _instance.GetType().GetMethod("StaticTestMethodNoBoxing");
_virtualInfo = _instance.GetType().GetMethod("VirtualTestMethod");
_staticDMD = DynamicMethodDelegateFactory.Create(_staticInfo);
_staticNoBoxingDMD = DynamicMethodDelegateFactory.Create(_staticNoBoxingInfo);
_virtualDMD = DynamicMethodDelegateFactory.Create(_virtualInfo);
// Perform tests.
TestStatic();
TestVirtual();
TestPerformanceOnStaticCalls();
TestPerformanceOnStaticNoBoxingCalls();
TestPerformanceOnVirtualCalls();
}
static void TestStatic()
{
Console.WriteLine("");
Console.WriteLine("== Testing static method invokation");
float a = 5.2f;
float b = 6;
object[] parms = { a, b};
Console.WriteLine(" " + a + " + " + b + " = " + _staticDMD(null, parms));
}
static void TestVirtual()
{
Console.WriteLine("");
Console.WriteLine("== Testing virtual method invokation");
object[] parms = { "car", 4, Color.Lime };
Console.WriteLine(" [Base class]: " + _virtualDMD(_instance, parms));
Console.WriteLine(" [Derived class]: " + _virtualDMD(_derivedInstance, parms));
}
static void TestPerformanceOnVirtualCalls()
{
// Test parameters. Change them if test runs too slowly on your machine.
int iterations = 10000;
int numTests = 5;
Console.WriteLine("");
Console.WriteLine("== Testing performance of dynamic method delegates");
Console.WriteLine("== Test call type: virtual method without boxing on return value");
object[] parms = { "car", 4, Color.Lime };
long dmdTime = 0;
long directTime = 0;
long invokeTime = 0;
Stopwatch watch;
for (int j = 0; j < numTests; j++)
{
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
_virtualDMD(_derivedInstance, parms);
}
dmdTime += watch.ElapsedMilliseconds;
}
dmdTime /= numTests;
for (int j = 0; j < numTests; j++)
{
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
_virtualInfo.Invoke(_derivedInstance, parms);
}
invokeTime += watch.ElapsedMilliseconds;
}
invokeTime /= numTests;
for (int j = 0; j < numTests; j++)
{
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
_derivedInstance.VirtualTestMethod("car", 4, Color.Lime);
}
directTime += watch.ElapsedMilliseconds;
}
directTime /= numTests;
float dmdEfficiency = (float)directTime / dmdTime;
float invokeEfficiency = (float)directTime / invokeTime;
Console.WriteLine(" Results for " + numTests + " tests on " + iterations + " iterations:");
Console.WriteLine(" Direct method call: " + directTime + "ms ");
Console.WriteLine(" Dynamic method delegates: " + dmdTime + "ms " +
"(Efficiency: " + dmdEfficiency.ToString("F2") + ")");
Console.WriteLine(" MethodInfo.Invoke: " + invokeTime + "ms " +
"(Efficiency: " + invokeEfficiency.ToString("F2") + ")");
}
static void TestPerformanceOnStaticCalls()
{
// Test parameters. Change them if test runs too slowly on your machine.
int iterations = 500000;
int numTests = 5;
Console.WriteLine("");
Console.WriteLine("== Testing performance of dynamic method delegates:");
Console.WriteLine("== Test call type: static method with boxing on return value");
float a = 5.2f;
float b = 6.3f;
object[] parms = { a, b };
long dmdTime = 0;
long directTime = 0;
long invokeTime = 0;
Stopwatch watch;
for (int j = 0; j < numTests; j++)
{
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
_staticDMD(null, parms);
}
dmdTime += watch.ElapsedMilliseconds;
}
dmdTime /= numTests;
for (int j = 0; j < numTests; j++)
{
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
_staticInfo.Invoke(null, parms);
}
invokeTime += watch.ElapsedMilliseconds;
}
invokeTime /= numTests;
for (int j = 0; j < numTests; j++)
{
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
TestClass.StaticTestMethod(a, b);
}
directTime += watch.ElapsedMilliseconds;
}
directTime /= numTests;
float dmdEfficiency = (float)directTime / dmdTime;
float invokeEfficiency = (float)directTime / invokeTime;
Console.WriteLine(" Results for " + numTests + " tests on " + iterations + " iterations:");
Console.WriteLine(" Direct method call: " + directTime + "ms ");
Console.WriteLine(" Dynamic method delegates: " + dmdTime + "ms " +
"(Efficiency: " + dmdEfficiency.ToString("F2") + ")");
Console.WriteLine(" MethodInfo.Invoke: " + invokeTime + "ms " +
"(Efficiency: " + invokeEfficiency.ToString("F3") + ")");
}
static void TestPerformanceOnStaticNoBoxingCalls()
{
// Test parameters. Change them if test runs too slowly on your machine.
int numTests = 5;
int iterations = 100000;
Console.WriteLine("");
Console.WriteLine("== Testing performance of dynamic method delegates:");
Console.WriteLine("== Test call type: static method without boxing on return value");
string a = "Foo";
string b = "Bar";
object[] parms = { a, b };
long dmdTime = 0;
long directTime = 0;
long invokeTime = 0;
Stopwatch watch;
for (int j = 0; j < numTests; j++)
{
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
_staticNoBoxingDMD(null, parms);
}
dmdTime += watch.ElapsedMilliseconds;
}
dmdTime /= numTests;
for (int j = 0; j < numTests; j++)
{
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
_staticNoBoxingInfo.Invoke(null, parms);
}
invokeTime += watch.ElapsedMilliseconds;
}
invokeTime /= numTests;
for (int j = 0; j < numTests; j++)
{
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
TestClass.StaticTestMethodNoBoxing(a, b);
}
directTime += watch.ElapsedMilliseconds;
}
directTime /= numTests;
float dmdEfficiency = (float)directTime / dmdTime;
float invokeEfficiency = (float)directTime / invokeTime;
Console.WriteLine(" Results for " + numTests + " tests on " + iterations + " iterations:");
Console.WriteLine(" Direct method call: " + directTime + "ms ");
Console.WriteLine(" Dynamic method delegates: " + dmdTime + "ms " +
"(Efficiency: " + dmdEfficiency.ToString("F2") + ")");
Console.WriteLine(" MethodInfo.Invoke: " + invokeTime + "ms " +
"(Efficiency: " + invokeEfficiency.ToString("F3") + ")");
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.