Question

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 https://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,

  1. If this IS the right methodology to speed up my dynamic calls, how can I assign the COM method MakeRecord to my Action delegate?

  2. 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");
Was it helpful?

Solution

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?
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top