1、序言
由于系统中涉及到Remoting、Reflection以及本地调用的应用,考虑到性能的问题,故做了此次测试。
测试环境为:操作系统为windows2003 server;开发平台为.Net 2005。
2、测试实现
测试方法如下:
在测试中,新建6个工程:TestObject、TestInterface、TestRemotingHost、RemotingPerfTest、ReflectPerfTest以及LocalPerfTest
1、TestObject是远程调用的对象,也是此次运行的方法的宿主类。其代码为:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace test.remoting
{
public class RemotingObject:MarshalByRefObject,IRemotingObject
{
public int Add(int Operand1, int Operand2)
{
return Operand1 + Operand2;
}
}
}
2、TestInterface为远程调用接口,客户端可以通过此接口对远程对象进行Remoting。其代码为:
using System;
using System.Collections.Generic;
using System.Text;
namespace test.remoting
{
public interface IRemotingObject
{
int Add(int op1, int op2);
}
}
3、TestRemotingHost为启动远程服务的类,它负责注册远程对象。其代码为:
private void btnStart_Click(object sender, EventArgs e)
{
try
{
lsbDescript.Items.Add("正在启动服务,请稍候……");
lsbDescript.Items.Add("服务启动完成!!!");
RemotingConfiguration.Configure("TestRemotingHost.exe.config");
}
catch(Exception ex)
{
lsbDescript.Items.Add(ex.Message);
}
}
TestRemotingHost.exe.config文件为:
4、RemotingPerfTest为测试远程调用的客户端。其代码为:
private void btnRunTest_Click(object sender, EventArgs e)
{
DateTime startTime = DateTime.Now;
txtResult.Text = "开始执行" + txtLoopNum.Text + "次循环,请等待…… /r/n";
for (int i = 0; i < Convert.ToInt32(txtLoopNum.Text); i++)
{
try
{
clientChannel = new HttpChannel(0);
ChannelServices.RegisterChannel(clientChannel);
IRemotingObject testObj = (IRemotingObject)Activator.GetObject(typeof(IRemotingObject), "http://localhost:4000/TestObj");
testObj.Add(i, i + 1);
ChannelServices.UnregisterChannel(clientChannel);
clientChannel = null;
}
catch (Exception ex)
{
ChannelServices.UnregisterChannel(clientChannel);
clientChannel = null;
txtResult.Text += (ex.Message);
}
}
TimeSpan timeSpan = DateTime.Now - startTime;
txtResult.Text += "总共花费了" + timeSpan.TotalSeconds + "秒" + "/r/n";
}
5、ReflectPerfTest为测试Reflection的客户端。其代码为:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
namespace test.remoting
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnRunTest_Click(object sender, EventArgs e)
{
DateTime startTime = DateTime.Now;
txtResult.Text = "开始执行" + txtLoopNum.Text + "次循环,请等待…… /r/n";
for (int i = 0; i < Convert.ToInt32(txtLoopNum.Text); i++)
{
//txtResult.Text += "2 * " + i + "+ 1 =" + GetResultByReflection(i, i + 1).ToString() + "/r/n";
GetResultByReflection(i, i + 1).ToString();
}
TimeSpan timeSpan = DateTime.Now - startTime;
txtResult.Text += "总共花费了" + timeSpan.TotalSeconds + "秒" + "/r/n";
}
private object GetResultByReflection(int op1, int op2)
{
Type type = null;
RemotingObject remotingObj = (RemotingObject)this.GetRemotingObjectInstance(out type);
MethodInfo method = type.GetMethod("Add");
//return remotingObj.Add(op1, op2);
object[] arg = { op1, op2 };
return method.Invoke(remotingObj, arg);
}
private object GetRemotingObjectInstance(out Type type)
{
Assembly[] asssemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int j = 0; j < asssemblies.Length; j++)
{
if (asssemblies[j].FullName.StartsWith("TestObject"))
{
Type[] types = asssemblies[j].GetTypes();
for (int i = 0; i < types.Length; i++)
{
if (types[i].FullName == "test.remoting.RemotingObject")
{
type = types[i];
return Activator.CreateInstance(types[i]);
}
}
}
}
type = null;
return null;
}
}
}
6、LocalPerfTest为测试本地调用的客户端。其代码为:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace test.remoting
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnRunTest_Click(object sender, EventArgs e)
{
RemotingObject remoteObj = new RemotingObject();
DateTime startTime = DateTime.Now;
txtResult.Text = "开始执行" + txtLoopNum.Text+ "次循环,请等待…… /r/n";
for (int i = 0; i < Convert.ToInt32(txtLoopNum.Text); i++)
{
//txtResult.Text += "2 * " + i + " + 1 =" + remoteObj.Add(i, i + 1) + "/r/n";
remoteObj.Add(i, i + 1);
}
TimeSpan timeSpan = DateTime.Now - startTime;
txtResult.Text += "总共花费了" + timeSpan.TotalSeconds + "秒" + "/r/n";
}
}
}
3、 测试结果
1、本地测试结果为:开始执行1000次循环,请等待……
总共花费了0.031251秒
2、Reflection测试结果为:开始执行1000次循环,请等待……
总共花费了0.1406286秒
3、Remoting测试结果为:开始执行1000次循环,请等待……
总共花费了21.437288秒
4、总结
也许每个人在自己机器上出现的结果不一样,但我们关心的是他们结果之间的比例,如,Reflection执行时间应该是本地执行的4-5倍,而Remoting则是本地测试的670多倍。