Какое минимальное снижение производительности связи Cross AppDomain?

Я пытаюсь свести к минимуму снижение производительности связи между доменами приложений на одном компьютере. В моем игрушечном примере класс A загружается в AppDomain 1. Он создает AppDomain 2 и загружает туда экземпляр Class 2 (Class 2 наследуется от MarshalByRef), возвращающий прокси. Затем Class 1 повторно вызывает метод на прокси, который не возвращает значений.

Я получаю следующие результаты:

  1. Нет доменов приложений, оба класса загружаются в один и тот же домен приложений, и первый вызов повторяет метод на втором (метод не имеет параметров): 24 миллиона вызовов метода / сек.
  2. Два AppDomain, как описано выше, метод не имеет параметров или строковых параметров: 340000 вызовов методов / сек.
  3. Два домена приложений, как описано выше, один сериализуемый параметр (массив из двух строк): 64 000 вызовов метода / сек.

Хотя я понимаю снижение производительности между 2 и 3 (сериализация), я действительно не понимаю, почему я в 100 раз медленнее от случая 1 к случаю 2. Насколько я понимаю, после создания прокси все последующие вызовы методов должны быть очень быстрыми, поскольку никакие данные не передаются из одного домена приложений в другой. Кто-нибудь сейчас почему общение через AppDomains так медленно? Я делаю что-то неправильно?

PS1. Единственный совет, который у меня есть по этому вопросу, здесь: "А стоимость пересечения границы AppDomain смущает". Я догадывался, что он имеет в виду сериализацию...

PS2. Я не считаю время создания AppDomain или Proxy (мои тесты начинаются с первого вызова метода)

PS3. Я использую.NET 3.5 в машине WinXP SP3. Я также пробовал.NET 4.0 Beta 1 без существенных различий.

3 ответа

Решение

Если вы подсчитаете количество линий IL, участвующих в каждом сценарии, вы увидите, что CLR выполняет намного больше, чем 100-кратную работу при удаленном взаимодействии. Прямой вызов - это всего лишь несколько кодов операций, но с удаленным взаимодействием задействовано несколько классов, реальные / прозрачные прокси, проверки безопасности, сериализация, yadda yadda yadda. Вы должны будете решить эту проблему с помощью дизайна - не существует волшебной палочки для улучшения перфекта через реализацию.

Есть ли способ, которым вы можете вызвать один вспомогательный метод, который принимает параметры о том, сколько раз вы хотите вызвать метод, который вам нужен? Производительность вызовов между доменами сильно зависит от реализации. Я считаю, что в CLR 4.0 это может быть значительно лучше, но я не совсем разбираюсь в деталях.

Однако, как правило, вы хотите избежать издержек, "пакетируя" вызовы через вспомогательный метод.

Я видел те же результаты. Я не могу объяснить, почему он намного медленнее, за исключением того, что он быстрее, чем запуск двух разных процессов и связь друг с другом. В моем дизайне я столкнулся с подобной дилеммой. В конце я изменил свой дизайн для создания независимых доменов приложений; домен приложения мог выполнять свою работу без необходимости связываться с другим доменом приложения во время выполнения... Он будет сообщать данные только после завершения.

Другие вопросы по тегам