Любые документы, в которых исследуются проблемы производительности и стратегии оптимизации, доступные для COM-приложений на основе C++?

Предостережение: я не уверен, что это можно считать правильным вопросом программирования SO!

Я столкнулся с серьезными потерями производительности при работе с пакетом MS Office, в основном из-за миллионов вызовов COM, которые я делаю для обработки документов. Часть проблемы была устранена с помощью OOXML SDK вместо использования собственного API приложения. Однако сам OOXML SDK выполняет вызовы COM, и это замедляет работу (да, я должным образом запустил встроенный анализатор производительности Visual Studio и BoundsChecker и убедился, что алгоритмы являются лучшими, которые мы можем использовать во всем). Я полагал, что слой кэширования значительно ускоряет работу (иногда сокращая время выполнения на одну четверть) (но, очевидно, ускорение зависит от моего шаблона доступа, который, в свою очередь, определяется структурой содержимого документа).

Учитывая тот факт, что и COM, и C++ существуют так долго, я удивлен, увидев, что так мало материалов по оптимизации COM-приложений на основе C++. (Быстрого поиска в Google должно быть достаточно, чтобы доказать мою точку зрения, хотя я не возражаю против того, чтобы оказаться неправым!)

  • Так что было бы здорово, если бы вы, ребята, помогли мне откопать несколько соответствующих документов из драг в Интернете.
  • Кроме того, (поскольку моя работа настолько очевидна), стоит ли все же описывать мой опыт в виде статьи?

Изменить: Уточнение: на самом деле я не ищу альтернативу (поскольку уже слишком поздно менять основу). Мне интересно почитать о похожих проблемах, с которыми люди, возможно, сталкивались в прошлом, и о том, как они обходились с ограничениями.


person dirkgently    schedule 16.06.2011    source источник
comment
Это хороший вопрос; Я бы сказал, что одним из лучших способов оптимизации приложений COM является их перенос из COM. COM накладывает массу накладных расходов, как концептуальных, так и реализационных.   -  person Paul Sonier    schedule 17.06.2011
comment
@Paul Sonier: Я бы сделал это, если бы мог. Иногда, как в случае со мной, других доступных альтернатив нет. Как еще написать плагин/общаться с офисными приложениями, если не через COM?   -  person dirkgently    schedule 17.06.2011
comment
@dirkgently: Насколько я знаю, они предоставляют управляемые расширения.   -  person Puppy    schedule 17.06.2011
comment
@DeadMG: Разве это не устарело? en.wikipedia.org/wiki/Managed_Extensions_for_C%2B%2B В любом случае, это слишком поздно переписывать всю эту чертову штуку (и есть какая-то причина придерживаться C++).   -  person dirkgently    schedule 17.06.2011
comment
@dirkgently: Managed Extensions to C++ - во-первых, он стал C++/CLI и все еще существует, а во-вторых, я имел в виду, что Office предоставляет управляемые точки входа.   -  person Puppy    schedule 17.06.2011
comment
@DeadMG: ME для C++ по-прежнему потребовало бы от нас много времени для разгона (и мы могли бы легко перейти на C# - это все так просто) :-)   -  person dirkgently    schedule 17.06.2011


Ответы (3)


Весьма вероятно, что С++ не виноват - скорее всего, это что-то вроде сортировки, которая срабатывает и занимает большую часть времени. Не забывайте, что у вас будет сортировка и для внутрипроцессных серверов — на случай, если модели потоковой передачи потребителя и сервера несовместимы. Также вы можете потратить много времени на синхронизацию в некоторых случаях.

Избавление от маршалинга или его оптимизация (есть такая вещь, как «беспоточный маршаллер», которого я сам не понимаю, но выглядит многообещающе с точки зрения повышения производительности) даст вам огромный импульс — каждый вызов будет идти напрямую, а не тонна проводки. Опять же, настройка синхронизации (сделав ее мелкозернистой и минимальной) также может повысить производительность.

Однажды у нас была серьезная проблема с производительностью в компоненте STA — вызовы из разных потребительских потоков проходили через прокси и сериализовались. Поскольку каждый вызов блокировался на длительный период времени (ожидая, пока бэкэнд выполнит сложную обработку данных), все остальные потоки просто висели в ожидании своей очереди — сервер обслуживал по одному запросу за раз. Мы изменили дизайн вызова — теперь он просто «отправляет» запрос, а событие COM срабатывает после завершения обработки. Это решило проблему — теперь «ожидание» было вынесено за пределы вызова, поэтому COM-синхронизация не блокировала слишком долго все потоки и не препятствовала параллелизму. Это не является чем-то специфичным для какого-либо языка — просто то, как работает параллелизм COM. Вы находите такие проблемы, тщательно регистрируя все звонки и просматривая журналы.

Когда вы спрашиваете о части C++, вы, конечно, можете профилировать - код C++ можно профилировать с большой детализацией. IMO, вряд ли вы найдете что-то стоящее внимания, но опять же, вы не знаете, пока не профилируете - может быть, в вашем коде есть что-то действительно глупое. Одна вещь, которую можно оптимизировать, — это минимизация безопасности потоков до уровня достаточно для вашей модели потоковой передачи.

person sharptooth    schedule 17.06.2011
comment
Острые наблюдения. Большое спасибо :-) Мой личный анализ проблемы был очень похож, если не точно такой же, на то, что вы написали в первом абзаце. Что касается потоков, у нас есть один читатель, за которым следует писатель. - person dirkgently; 17.06.2011
comment
@dirkgently: Хорошо, теперь, если это компонент STA, будет иметь большое значение, создан ли он в потоке записи или в потоке чтения, в зависимости от того, делает ли больше вызовов читатель или писатель. - person sharptooth; 17.06.2011

COM независим от языка/платформы по своему замыслу.
Таким образом, поиск методов оптимизации, специфичных для C++, немного выпадает из контекста. Для платформы COM и COM-серверов клиент C++ — это всего лишь один из клиентов, только работающий в более оптимизированном машинном коде.

COM — это протокол/архитектура для взаимодействия/коммуникации между сервером и клиентом.
Таким образом, минимизация самого доступа к серверу будет важнее, чем оптимизация операции доступа к серверу.

С другой стороны, некоторые COM-серверы предоставляют низкоуровневые интерфейсы, доступные только клиентам C/C++. Думаю, лучшим примером является элемент управления IE WebBrowser. Для этих COM-серверов использование C++ может привести к значительному повышению производительности. Но пакет MS Office AFAIK не предоставляет интерфейсы такого низкого уровня.

То есть весьма вероятно, что независимо от того, создаете ли вы модуль доступа к пакету MS Office на C++, C# или VB6, затраты на обработку, специфичные для COM (вызов методов интерфейса COM-сервера и получение результатов), могут быть измерены одинаково.

Я думаю, что клиенты C++ имеют больше вариантов оптимизации в области, не связанной с COM, и это должно быть ключевым моментом в подходе к оптимизации (например, введение резервного копирования локального кеша, как вы уже сделали).

person 9dan    schedule 16.06.2011
comment
1) Нет доступа к серверу. Обработка происходит на том же компьютере, на котором открыт документ. 2) Хотя теоретически вы правы, у меня очень плохое предчувствие по поводу качества производительности binding собственной реализации C++ для COM-интерфейсов. У меня есть один и тот же фрагмент кода на С# и С++, и первый превосходит второй. 3) Мое кеширование только минимизировало COM-вызовы. - person dirkgently; 17.06.2011
comment
C++ на самом деле не имеет COM-привязку и не нуждается в ней. COM в значительной степени определяется тем, как компилятор MSVC делал vtables. Таким образом, динамическая диспетчеризация COM обходится точно так же дорого, как обычный виртуальный вызов. (Кросс-процесс и кросс-серверная маршаллинг, очевидно, добавляют к этому, но все они начинаются с обычного COM-вызова внутрипроцессной заглушки, т.е. безразличны к языку вызова) - person MSalters; 25.06.2011

Просто проверяю очевидное: COM везде использует BSTR, которые содержат WCHAR[]. Используют ли ваши приложения WCHAR или вы переключаетесь между char и WCHAR при каждом вызове?

person MSalters    schedule 17.06.2011