Оптимизация вызовов методов для динамического типа

У меня есть следующий код, который создает экземпляр зарегистрированного COM-объекта

private dynamic server = null // Global variable.
...
Type type = Type.GetTypeFromProgID("Svr.GrpCall");
this.server = Activator.CreateInstance(type);

Я могу просто вызывать методы из этого объекта COM/dynamic, используя очень интуитивно понятную нотацию.

string expectedResult = this.server.GroupInit(someString, someBoolean);

Для одиночных вызовов производительность вызова таких методов через среду выполнения динамического языка (DLR) приемлема. Однако для одного требования мне нужно использовать двойной цикл for для тысяч записей, который использует метод в COM-объекте, который возвращает void

for (int i = 0; i < MAXREC; i++)
    for (int j = 0; j < MAXFIELDS; j++)
        this.server.MakeRecord(s1, s2, str);

Это ОЧЕНЬ медленно. Я знаю об этом, и ответ Эрика Липперта https://stackoverflow.com/a/7480977/626442 дает точную причину этого узкого места производительности.

Чтобы обойти это, я попытался определить глобальный Action для метода MakeRecord, который находится под давлением.

private Action<short, short, string> makeRecord;

где планируется использовать это в цикле for выше. Прежде чем использовать этот Action, я пытаюсь сначала инициализировать сервер (как указано выше), а затем назначить делегата makeRecord методу COM, используя

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);

Но type.GetMethod("MakeRecord") возвращает null. Итак, мой вопрос,

  1. Если эта ЯВЛЯЕТСЯ правильной методологией для ускорения моих dynamic вызовов, как мне назначить COM-метод MakeRecord моему делегату Action?

  2. Если это НЕ правильный метод для ускорения моих звонков dynamic, то что?

Спасибо за ваше время.


Я также пытался сделать

object o = Activator.CreateInstance(type);
MethodInfo methodInfo = o.GetType().GetMethod("MakeRec");

person MoonKnight    schedule 26.03.2014    source источник


Ответы (1)


Откуда вы знаете, что медленное поведение связано с использованием dynamic?

  • Пробовали ли вы использовать строго типизированные управляемые оболочки для COM-интерфейсов и вызывать их напрямую (т. е. без использования dynamic и без использования каких-либо методов отражения)? Вы можете добавить ссылку на саму сборку COM, чтобы автоматически создать управляемую оболочку.
  • Пробовали ли вы запускать свой код вне отладчика? Выполнение кода в отладчике приводит к снижению производительности до 100:1 для вызовов методов собственного кода, включая вызовы COM-интерфейса.
  • Рассматривали ли вы возможность обновления интерфейса, чтобы обеспечить более прямую реализацию желаемого алгоритма, чтобы вы могли делать меньше вызовов функций в управляемом коде?
person Sam Harwell    schedule 26.03.2014
comment
Как в профилировщике вы различали накладные расходы dynamic и стоимость самого метода? Если MakeRecord сам по себе медленный метод, то не имеет значения, используете ли вы dynamic, потому что это не узкое место. - person Sam Harwell; 26.03.2014
comment
Да, я знаю об этом. Причина, по которой я знаю, что этот метод «немедленный», заключается в том, что устаревшая библиотека COM поставляется со старым примером приложения VB6. Это приложение может вызывать COM-методы «напрямую», и это может вызывать MakeRecord 6000 раз за 5 секунд. Когда я выполняю точно такую ​​же операцию на С#, используя dynamic, на этот раз (для точно такого же набора данных) увеличивается примерно до 1 минуты. Еще раз спасибо за ваше время... - person MoonKnight; 26.03.2014
comment
Сэм, я отсутствовал какое-то время, прежде чем ответить на ваш комментарий, потому что я отсутствовал, просматривая ваш профиль - › ANTLR - › выступление Теренса Парра - › покупка книги и др.! Я поражен этой работой. Недавно я написал универсальную подсветку синтаксиса (ничего не сравнится с ANTLR), а недавно меня попросили переписать старый компилятор/статический анализатор C++ для некоторого псевдокода, используемого в страховой отрасли, а также добавить различные языковые форматы... - person MoonKnight; 26.03.2014
comment
Сначала я «сглотнул», думая, что это будет тяжело (но весело), ​​а потом нашел ANTLR! Не могли бы вы отправить вам по электронной почте несколько кратких вопросов об ANTLR, прежде чем я начну свою полную атаку? - person MoonKnight; 26.03.2014