Как правило, наблюдается заметная производительность при вызове PInvoke по методам Win32/COM?
Мне интересно, есть ли у кого-то достойное объяснение или обзор негативных аспектов использования DLLImport/PInvoke для Win32-методов из управляемого кода .NET?
Я планирую использовать различные методы Win32 и хотел бы получить более полное представление о негативных последствиях этого.
Спасибо,
Брайан.
Ответы
Ответ 1
Согласно MSDN - вызов собственных функций из управляемого кода
PInvoke имеет накладные расходы от 10 до 30 инструкций x86 для каждого звонка. В дополнение к этой фиксированной стоимости маршалинг создает дополнительные накладные расходы. Нет никакой платы за марширование между типами blittable, которые имеют одинаковое представление в управляемом и неуправляемом коде. Например, нет никакой стоимости для перевода между int и Int32.
По моему опыту, определенно есть накладные расходы, когда P/Invoking нативные функции, но обычно поражение производительности не стоит беспокоиться. Стоимость маршалинга - это то, что нужно помнить. Если вы проходите в больших структурах, строках и т.д., То быстродействие будет быстро отображаться.
Для P/вызываемых функций, которые вызываются очень часто, вы можете захотеть добавить [SuppressUnmanagedCodeSecurity]
к вашим определениям функций P/Invoke (см. MSDN - SuppressUnmanagedCodeSecurityAttribute). Это останавливает выполнение времени выполнения стека, чтобы гарантировать, что у вызывающего есть разрешение UnmanagedCode. Разумеется, перед добавлением этого атрибута убедитесь, что вы понимаете разветвления безопасности.
Ответ 2
Вот некоторые проблемы, которые я вижу с помощью PInvoke:
- Параметрирование маршалинга может быть дорогостоящим, в зависимости от типа данных (blittable/non-blittable)
- Правильное параметрическое маршалинг часто не очень интуитивно понятен.
- PInvoke не обеспечивает защиту времени компиляции. Можно легко пропустить имена DLL или функций без компилятора.
Если вы планируете использовать множество неуправляемых функций, я бы создал смешанную DLL (http://msdn.microsoft.com/en-us/library/x0w2664k.aspx), а не объявлял кучу PInvokes.
Ответ 3
я знаю, что этот вопрос старый, но мне удалось невероятно быстро вызывать нативные функции, используя не только инструкцию CIL calli, но и специальный трюк, но, конечно, вам нужно самостоятельно обрабатывать аргументы pinnig и/или marshalling, если вы имеете дело со сложными типами, включая строки.,