优化动态类型的方法调用 [英] Optimising Method Calls on Dynamic Type
问题描述
我有以下代码实例化注册的COM对象
private dynamic server = null //全局变量。
...
类型type = Type.GetTypeFromProgID(Svr.GrpCall);
this.server = Activator.CreateInstance(type);
我可以从这个COM / 动态
对象只是很好使用非常直观的符号
string expectedResult = this.server.GroupInit(someString,someBoolean);
对于单个调用,通过动态语言运行时(DLR)调用此类方法的性能是适合的。然而,对于一个需求,我需要为成千上万条记录使用一个< c>循环,它使用COM对象中的方法返回
void
for(int i = 0; i for j = 0; j this.server.MakeRecord(s1,s2,str);
这是
为了解决这个问题,我尝试为 MakeRecord <>定义一个全局
Action
/ code>处于压力下的方法
private Action< short,short,string& makeRecord;
其中计划是在上面的for循环中使用它。在使用此 Action
之前,我尝试首先初始化服务器(如上所述),然后将 makeRecord
COM方法使用
类型type = Type.GetTypeFromProgID(Svr.GrpCall);
this.server = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod(MakeRecord);
makeRecord =(Action< short,short,string>)Delegate.CreateDelegate(type,methodInfo);
但 type.GetMethod(MakeRecord)
正在返回 null
。因此,我的问题是:
-
如果这是 >加快我的
加快我的动态
调用,我如何分配COM方法MakeRecord
到我的动态
调用,是什么?
我也尝试过
object o = Activator.CreateInstance(type);
MethodInfo methodInfo = o.GetType()。GetMethod(MakeRec);
您如何知道缓慢的行为是由于使用动态
?
- 您尝试过使用强类型管理包装器COM接口并直接调用它们(即不使用
dynamic
并且不使用任何反射方法)?您可以添加对COM程序集本身的引用,以自动创建托管包装器。 - 您是否尝试过在调试器之外运行代码在调试器中运行代码会导致对本地代码的方法调用(包括COM接口调用)的性能损失达到100:1。
- 您是否考虑过更新接口以提供更直接实现所需的算法,以便在托管代码中减少函数调用?
I have the following code that instantiates a registered COM object
private dynamic server = null // Global variable.
...
Type type = Type.GetTypeFromProgID("Svr.GrpCall");
this.server = Activator.CreateInstance(type);
I can invoke methods from this COM/dynamic
object just fine using very intuitive notation
string expectedResult = this.server.GroupInit(someString, someBoolean);
For single calls the performance of calling such methods through the Dynamic Language Runtime (DLR) is liveable. However, for one requirement I need to use a double for
loop for thousands of records, which uses a method in the COM object that returns void
for (int i = 0; i < MAXREC; i++)
for (int j = 0; j < MAXFIELDS; j++)
this.server.MakeRecord(s1, s2, str);
This is MASSIVELY slow. I am aware of this and Eric Lippert's answer http://stackoverflow.com/a/7480977/626442 gives the exact cause of this performance bottle-neck.
To get around this I have attempted to define a global Action
for the MakeRecord
method that is under pressure
private Action<short, short, string> makeRecord;
where the plan is to use this in the for loop above. Before using this Action
, I attempt to first initialise the server (as above) and then assign the makeRecord
delegate to the COM method using
Type type = Type.GetTypeFromProgID("Svr.GrpCall");
this.server = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("MakeRecord");
makeRecord = (Action<short, short, string>)Delegate.CreateDelegate(type, methodInfo);
But the type.GetMethod("MakeRecord")
is returning null
. So, my question is,
If this IS the right methodology to speed up my
dynamic
calls, how can I assign the COM methodMakeRecord
to myAction
delegate?If this IS NOT the right methodology to speed up my
dynamic
calls, what is?
Thanks for your time.
I have also tried doing
object o = Activator.CreateInstance(type);
MethodInfo methodInfo = o.GetType().GetMethod("MakeRec");
How do you know the slow behavior is due to the use of dynamic
?
- Have you tried using strongly-typed managed wrappers for the COM interfaces and calling them directly (i.e. without using
dynamic
and without using any reflection methods)? You can add a reference to the COM assembly itself to create the managed wrapper automatically. - Have you tried running your code outside the debugger? Running code in the debugger results in up to a 100:1 performance hit for method calls to native code, which includes COM interface calls.
- Have you considered updating the interface to provide a more direct implementation of the desired algorithm, such that you can make fewer function calls in managed code?
这篇关于优化动态类型的方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!