Работая с Outlook object model я обнаружил при помощи профайлера что метод QueryInterface работает очень медленно, соизмеримо производительность метода ADODB::Command::Execute. Конткретно я преобразую IDispatch указатель возвращаемый для каждого Outlook Item в соответствющий тип, например Outlook::_MailItem. Затем ссохраняю свойства MailItem в BD. Так вот 40 процентов времени занимает именно выполнение QueryInterface. Как по мне это недопстимое расточительство всего лишь для приведения типа.
А>Есть ли у кого нибудь какие либо идеи?
Так как _MailItem — это диспинтерфейс, соответственно это IDispatch посему можно вообще QI не делать...
... << RSDN@Home 1.1 beta 1 >>
Народная мудрось
всем все никому ничего(с).
Re[2]: Можно ли ускорить QueryIintrface
От:
Аноним
Дата:
29.09.03 07:14
Оценка:
Здравствуйте, Tom, Вы писали:
А>>Есть ли у кого нибудь какие либо идеи? Tom>Так как _MailItem — это диспинтерфейс, соответственно это IDispatch посему можно вообще QI не делать...
Но каким образом я могу использовать интерфейс IDispatch для доступа к интерфейсу MailItem?
Приведите пожалуйста небольшой пример кода как можно обойтиссь без QueryInterface.
Или как узнать точно тип объекта по указателю на IDispatch не прриводя его к конкретном типу с помощью QueryInterface?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Tom, Вы писали:
А>>>Есть ли у кого нибудь какие либо идеи? Tom>>Так как _MailItem — это диспинтерфейс, соответственно это IDispatch посему можно вообще QI не делать...
А>Но каким образом я могу использовать интерфейс IDispatch для доступа к интерфейсу MailItem?
Здравствуйте, Снорк, Вы писали:
С>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, Tom, Вы писали:
А>>>>Есть ли у кого нибудь какие либо идеи? Tom>>>Так как _MailItem — это диспинтерфейс, соответственно это IDispatch посему можно вообще QI не делать...
А>>Но каким образом я могу использовать интерфейс IDispatch для доступа к интерфейсу MailItem?
С>Через Invoke. Примеры — в MSDN.
А>Но каким образом я могу использовать интерфейс IDispatch для доступа к интерфейсу MailItem? А>Приведите пожалуйста небольшой пример кода как можно обойтиссь без QueryInterface. А>Или как узнать точно тип объекта по указателю на IDispatch не прриводя его к конкретном типу с помощью QueryInterface?
Если ты используешь смартпоинтер _MailItemPtr то можешь вызвать _MailItemPtr.Attach(pUnk) либо ручками через IDispatch::Invoke(...)
Здравствуйте, Tom, Вы писали:
А>>Но каким образом я могу использовать интерфейс IDispatch для доступа к интерфейсу MailItem? А>>Приведите пожалуйста небольшой пример кода как можно обойтиссь без QueryInterface. А>>Или как узнать точно тип объекта по указателю на IDispatch не прриводя его к конкретном типу с помощью QueryInterface?
Tom>Если ты используешь смартпоинтер _MailItemPtr то можешь вызвать _MailItemPtr.Attach(pUnk) либо ручками через IDispatch::Invoke(...)
Но ведь _MailItemPtr.Attach(pUnk) вовсе не будет работать не говоря о том что это даже не откомпилируется.
А IDispatch::Invoke(...) работает также медленно как и QueryInterface. Насколько я понял оба эти метода подгружают реализацию интерфейса в run-time т.е. где то в их недрах есть LoadLibrary или что то в этом духе ... я не специалист в СОМ. Единственный наверное способ ускорить преобразоввание типа — статически прилинковать нужную библиотеку ... но как это можно сделать ... ессли вообще можно.
Здравствуйте, Снорк, Вы писали:
С>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, Tom, Вы писали:
А>>>>Есть ли у кого нибудь какие либо идеи? Tom>>>Так как _MailItem — это диспинтерфейс, соответственно это IDispatch посему можно вообще QI не делать...
А>>Но каким образом я могу использовать интерфейс IDispatch для доступа к интерфейсу MailItem?
С>Через Invoke. Примеры — в MSDN.
А IDispatch::Invoke(...) работает также медленно как и QueryInterface. Насколько я понял оба эти метода подгружают реализацию интерфейса в run-time т.е. где то в их недрах есть LoadLibrary или что то в этом духе ... я не специалист в СОМ. Единственный наверное способ ускорить преобразоввание типа — статически прилинковать нужную библиотеку ... но как это можно сделать ... ессли вообще можно.
V_M>А IDispatch::Invoke(...) работает также медленно как и QueryInterface. Насколько я понял оба эти метода подгружают реализацию интерфейса в run-time т.е. где то в их недрах есть LoadLibrary или что то в этом духе ... я не специалист в СОМ.
IDispatch::Invoke и QueryInterface связаны с маршалингом, хоть и по разной причине. Как правило, затраты на Invoke несравнимо выше чем на QueryInterface. Если они работают одинаково и медленно, то есть основания считать, что так задумано. Например, для затруднения работы — нормальный юзер подождет, спаммеру же ждать некогда, ему спам слать надо. Хотя это к слову, я с мылом не работал, точно не знаю.
Хотя я так и не понял твоих затруднений — сохранение СОМ объектов где-либо делается через IPersist* интерфейсы и к IDispatch-у (или другим) никакого отношения, в принципе, не имеют. Привел бы часть кода, что ли.
V_M>Единственный наверное способ ускорить преобразоввание типа — статически прилинковать нужную библиотеку ... но как это можно сделать ... ессли вообще можно.
А вот это заблуждение: в СОМе не нужно прилинковывать какие-либо библиотеки. Не царское это дело. Да и не получится.
V_M>Но ведь _MailItemPtr.Attach(pUnk) вовсе не будет работать не говоря о том что это даже не откомпилируется.
Откомпилируется и будет работать. В чём то сомнения?
V_M>А IDispatch::Invoke(...) работает также медленно как и QueryInterface. Насколько я понял оба эти метода подгружают реализацию интерфейса в run-time т.е. где то в их недрах есть LoadLibrary или что то в этом духе ... я не специалист в СОМ.
QI и IDispatch::Invoke — 2 метода для разных целей. У автора вопроса была задержка с именно QI!
V_M>Единственный наверное способ ускорить преобразоввание типа — статически прилинковать нужную библиотеку ... но как это можно сделать ... ессли вообще можно.
Никаких способов изменить поведение диспинтерфейса нет и эти домослы которые вы пишете — бред.
Здравствуйте, Vi2, Вы писали:
Vi2>Здравствуйте, Vadym_M, Вы писали:
Vi2>
V_M>>А IDispatch::Invoke(...) работает также медленно как и QueryInterface. Насколько я понял оба эти метода подгружают реализацию интерфейса в run-time т.е. где то в их недрах есть LoadLibrary или что то в этом духе ... я не специалист в СОМ.
Vi2>IDispatch::Invoke и QueryInterface связаны с маршалингом, хоть и по разной причине. Как правило, затраты на Invoke несравнимо выше чем на QueryInterface. Если они работают одинаково и медленно, то есть основания считать, что так задумано. Например, для затруднения работы — нормальный юзер подождет, спаммеру же ждать некогда, ему спам слать надо. Хотя это к слову, я с мылом не работал, точно не знаю.
Vi2>Хотя я так и не понял твоих затруднений — сохранение СОМ объектов где-либо делается через IPersist* интерфейсы и к IDispatch-у (или другим) никакого отношения, в принципе, не имеют. Привел бы часть кода, что ли. Vi2>
V_M>>Единственный наверное способ ускорить преобразоввание типа — статически прилинковать нужную библиотеку ... но как это можно сделать ... ессли вообще можно.
Vi2>А вот это заблуждение: в СОМе не нужно прилинковывать какие-либо библиотеки. Не царское это дело. Да и не получится.
Спасибо за разъяснение ...
Как я уже писал в начале — моя задача сохранить MailItem в базе данных Access. Я не знаком с IPersist* пока ... он может ускорить работу в данном случае?
Здравствуйте, Tom, Вы писали:
V_M>>Но ведь _MailItemPtr.Attach(pUnk) вовсе не будет работать не говоря о том что это даже не откомпилируется. Tom>Откомпилируется и будет работать. В чём то сомнения?
Пробовал — не компилируется ... да и не должно в принципе (хотя зависит от реализации). При создании смартпоинтера если передать IDispatch в качестве параметра конструктора — тогда да ... а с Attach такой фокус не вызходит. Да и какая вобщем то разница если смартпоинттер сам использует QI для приведения типа.
V_M>>А IDispatch::Invoke(...) работает также медленно как и QueryInterface. Насколько я понял оба эти метода подгружают реализацию интерфейса в run-time т.е. где то в их недрах есть LoadLibrary или что то в этом духе ... я не специалист в СОМ. Tom>QI и IDispatch::Invoke — 2 метода для разных целей. У автора вопроса была задержка с именно QI!
V_M>>Единственный наверное способ ускорить преобразоввание типа — статически прилинковать нужную библиотеку ... но как это можно сделать ... ессли вообще можно. Tom>Никаких способов изменить поведение диспинтерфейса нет и эти домослы которые вы пишете — бред.
Да уж извините за "бред' ... но это действительно размышления в слуух.
V_M>Пробовал — не компилируется ... да и не должно в принципе (хотя зависит от реализации). При создании смартпоинтера если передать IDispatch в качестве параметра конструктора — тогда да ... а с Attach такой фокус не вызходит. Да и какая вобщем то разница если смартпоинттер сам использует QI для приведения типа.
Должно! Код показывай. А Attach нужен как раз что бы QI избежать.
Здравствуйте, Tom, Вы писали:
V_M>>Пробовал — не компилируется ... да и не должно в принципе (хотя зависит от реализации). При создании смартпоинтера если передать IDispatch в качестве параметра конструктора — тогда да ... а с Attach такой фокус не вызходит. Да и какая вобщем то разница если смартпоинттер сам использует QI для приведения типа. Tom>Должно! Код показывай. А Attach нужен как раз что бы QI избежать.
Вот код ...
inline bool MailItemDataExtractor::IsMailItem(IDispatchPtr pItem, _MailItemPtr& pMailItem)
{
try
{
//pItem->QueryInterface(__uuidof(_MailItem), (LPVOID*)&pMailItem); // Это прежняя версия
pMailItem.Attach(pItem); // IDispatch* не может быть приведен к структуре _MailItem
}
catch(...)
{
return false;
}
Здравствуйте, Tom, Вы писали:
V_M>>Пробовал — не компилируется ... да и не должно в принципе (хотя зависит от реализации). При создании смартпоинтера если передать IDispatch в качестве параметра конструктора — тогда да ... а с Attach такой фокус не вызходит. Да и какая вобщем то разница если смартпоинттер сам использует QI для приведения типа. Tom>Должно! Код показывай. А Attach нужен как раз что бы QI избежать.
Здравствуйте, Tom, Вы писали:
V_M>>Пробовал — не компилируется ... да и не должно в принципе (хотя зависит от реализации). При создании смартпоинтера если передать IDispatch в качестве параметра конструктора — тогда да ... а с Attach такой фокус не вызходит. Да и какая вобщем то разница если смартпоинттер сам использует QI для приведения типа. Tom>Должно! Код показывай. А Attach нужен как раз что бы QI избежать.
Я показал образец кода как Вы и просили (см предыдущие ответы)... но я не вижу Вашего ответа ... Я так понимаю у Вас ничего не вышло с Attach?