2009-07-17 11 views
18

Estoy tratando de minimizar la penalización de rendimiento de la comunicación entre AppDomains en la misma máquina. En mi ejemplo de juguete, la Clase A se carga en AppDomain 1. Crea un AppDomain 2 y carga allí una instancia de Clase 2 (Clase 2 hereda de MarshalByRef) obteniendo un proxy. Luego, la Clase 1 llama repetidamente a un método en el proxy que no devuelve ningún valor.¿Cuál es la penalización mínima en el rendimiento de comunicación Cross AppDomain?

puedo obtener los siguientes resultados:

  1. No hay dominios de aplicación, ambas clases se cargan en el mismo dominio de aplicación y las primeras llamadas repetedly el método en el segundo (el método no tiene parámetros): 24 millones método llamadas/seg
  2. dos dominio de aplicación como se describe anteriormente, el método no tiene parámetros o "sangrado" parámetros de cadena: 340.000 métodos llamadas/sec
  3. dos dominios de aplicación como se describe anteriormente, un parámetro serializable (array de dos cuerdas s): 64.000 llamadas de método/seg

Aunque entiendo la penalización de rendimiento entre 2 y 3 (serialización), realmente no entiendo por qué estoy 100 veces más lento de caso a caso 1 2 . A mi entender, una vez que se crea el proxy todas las invocaciones subsecuentes de métodos deben ser realmente rápidas ya que no se están organizando datos de un AppDomain a otro. ¿Alguien ahora por qué comunicarse en AppDomains es tan lento? ¿Estoy haciendo algo mal?

PS1. El único consejo que tengo sobre esto es here: "Y el costo de cruzar un límite de AppDomain es vergonzoso". Supongo que se refiere a la serialización ...

PS2. No cuento el tiempo de creación de AppDomain o Proxy (mis puntos de referencia comienzan en la primera invocación de método)

PS3. Estoy usando .NET 3.5 en una máquina WinXP SP3. También probé .NET 4.0 Beta 1 sin diferencias significativas.

Respuesta

11

Si cuenta las líneas de IL involucradas en cada escenario, verá que el CLR está haciendo mucho más de 100 veces el trabajo cuando se comunica de forma remota. Una invocación directa es solo unos pocos códigos de operación, pero con la comunicación remota hay múltiples clases involucradas, proxies reales/transparentes, comprobaciones de seguridad, serialización, yadda yadda yadda. Tendrá que abordar esto a través del diseño; no existe una solución mágica para mejorar el desempeño a través de la implementación.

+1

+1 Estoy de acuerdo contigo por completo. Una simple llamada directa al método es extremadamente simple. Una llamada a método a través de ** remoting ** es mucho más pesada. La sobrecarga es mucho más grande. La única solución real es un buen diseño de aplicación que no dependería de la velocidad de la comunicación cruzada de AppDomain. – jpbochi

1

¿Hay alguna manera de llamar a un solo método de ayuda que toma parámetros sobre cuántas veces quiere llamar al método que necesita? El rendimiento de las llamadas de Cross-AppDomain varía mucho según la implementación. Creo que podría ser significativamente mejor en el CLR 4.0, pero no estoy completamente al tanto de los detalles allí.

Sin embargo, en general, desea evitar la sobrecarga "agrupando" las llamadas a través de un método de ayuda.

+0

No veo cómo me va a ayudar. El método de mi Clase A hace exactamente eso: llama continuamente a object.MyMethod().Si el costo de una llamada en un proxy es 100 veces más grande que una llamada en un mismo objeto AppDomain, el impacto en mi diseño será enorme. – Yiannis

+3

Llamar object.MyHelperMethod, que llama a object.MyMethod repetidamente en el otro AppDomain. Si necesita el rendimiento y supuso/requería una alta velocidad entre dominios de AppDomain, entonces sí, podría tener un gran impacto en su diseño. –

+0

¡Ohh, ya veo ...! :-) OK, esto por supuesto hará las cosas rápido. ¡Pero este ejemplo es solo un juguete, mi programa real no llamará a la misma función 20 mil veces por segundo ...! Tendré que hacer varias llamadas de AppDomain cruzadas que deben ser rápidas en general. Thnanks de todos modos! – Yiannis

0

He visto los mismos resultados. No puedo explicar por qué es mucho más lento, excepto que es más rápido tener dos procesos diferentes ejecutándose y comunicándose entre sí. En mi diseño, me enfrenté a un dilema similar. Al final, modifiqué mi diseño para crear dominios de aplicaciones independientes; el dominio de la aplicación pudo hacer su trabajo sin la necesidad de comunicarse con otro dominio de la aplicación durante la ejecución ... Solo informaría los datos cuando se completaran.

Cuestiones relacionadas