性能测试
C++/CLI 反射性能测试
为了测试 C++/CLI 反射调用两种方案(直接反射调用,委托方法调用)的效率,我们循环1000次测试,下面是测试代码:
NetLibProxy::UserProxy^ proxy = gcnew NetLibProxy::UserProxy("..NetLibbinDebugNetLib.dll");
std::list<CppUserInfo> list = proxy->GetUsers("张");
System::Console::WriteLine("C++ Get List data From .NET function,OK.");
System::Diagnostics::Stopwatch^ sw = gcnew System::Diagnostics::Stopwatch;
sw->Start();
for (int i = 0; i<1000; i++)
proxy->SaveUsers(list);
sw->Stop();
System::Console::WriteLine("1,1000 loop,C++ Post List data To .NET function,OK.use time(ms):{0}",sw->ElapsedMilliseconds);
sw->Restart();
for(int i=0;i<1000;i++)
proxy->SaveUsers2(list);
sw->Stop();
System::Console::WriteLine("2,1000 loop,C++ Post List data To .NET function,OK..use time(ms):{0}", sw->ElapsedMilliseconds);
不调试,直接执行:
C++ Get List data From .NET function,OK.
1,1000 loop,C++ Post List data To .NET function,OK.use time(ms):65
2,1000 loop,C++ Post List data To .NET function,OK..use time(ms):48
可见,虽然在.NET程序端,我们使用了弱类型的泛型集合,综合起来还是反射+委托方法执行,效率要高。
所以如果你能够适当对要调用的.NET方法进行封装,那么可采用使用弱类型集合传输数据的方案,否则,就在C++/CLI端多写2行代码,使用强类型传输数据的方案。
与.NET直接调用和反射的性能比较
在本篇的方案中,都是C++反射来调用.NET方法的,如果都是在.NET应用程序中直接调用或者反射.NET方法,性能差距有多少呢?
我们模拟文中 C++/CLI的UserProxy,写一个.NET中的 UserProxy:
struct UserStruct
{
public int ID;
public string Name;
public DateTime Birthday;
}
class UserProxy
{
User user;
public UserProxy()
{
user = new User();
}
public List<UserStruct> GetUsers(string likeName)
{
List<UserStruct> result = new List<NetApp.UserStruct>();
var list = user.GetUsers(likeName);
foreach (var item in list)
{
UserStruct us;
us.ID = item.ID;
us.Name = item.Name;
us.Birthday = item.Birthday;
result.Add(us);
}
return result;
}
public bool SaveUsers(IList<UserStruct> users)
{
List<IUserInfo> list = new List<IUserInfo>();
IUserInfo userObj = user.CreateUserObject();
foreach (var item in users)
{
IUserInfo currUser = (IUserInfo)((ICloneable)userObj).Clone();
currUser.ID = item.ID;
currUser.Name = item.Name;
currUser.Birthday = item.Birthday;
list.Add(currUser);
}
bool result = user.SaveUsers(list);
return result;
}
Object CreateUserObject()
{
MethodInfo method = user.GetType().GetMethod("CreateUserObject", BindingFlags.Public | BindingFlags.Instance);
Func<Object> fun = (Func<Object>)Delegate.CreateDelegate(typeof( Func<Object>), user, method);
return fun();
}
//反射+委托
public bool SaveUsers2(IList<UserStruct> users)
{
MethodInfo method = user.GetType().GetMethod("SaveUsers2", BindingFlags.Public | BindingFlags.Instance);
Func<System.Collections.Generic.IEnumerable<Object>, bool> fun2 = (Func<System.Collections.Generic.IEnumerable<Object>, bool>)Delegate.CreateDelegate(typeof( System.Func<System.Collections.Generic.IEnumerable<Object>, bool>),
user, method);
List<IUserInfo> list = new List<IUserInfo>();
object userObj = CreateUserObject();
foreach (var item in users)
{
IUserInfo currUser = (IUserInfo)((ICloneable)userObj).Clone();
currUser.ID = item.ID;
currUser.Name = item.Name;
currUser.Birthday = item.Birthday;
list.Add(currUser);
}
bool result = fun2(list);
return result;
}
}
.Net UserProxy










