2009-07-17 12 views
18

Sto cercando di ridurre al minimo la penalità di prestazioni della comunicazione tra AppDomains nello stesso computer. Nel mio esempio di esempio, la classe A viene caricata in AppDomain 1. Crea un AppDomain 2 e carica lì un'istanza di Class 2 (la classe 2 eredita da MarshalByRef) restituendo un proxy. Quindi la classe 1 chiama ripetutamente un metodo sul proxy che non restituisce alcun valore.Qual è la penalità minima per le prestazioni di comunicazione Cross AppDomain?

ottengo i seguenti risultati:

  1. Nessun AppDomain, entrambe le classi vengono caricate nello stesso dominio di applicazione e le prime chiamate repetedly il metodo sul secondo (il metodo non ha parametri): 24 milioni metodo chiamate/sec
  2. due AppDomain come sopra descritto, il metodo non ha parametri o "bleeding" parametri stringa: 340.000 metodi invita/sec
  3. due AppDomain come descritto sopra, un parametro serializable (array di due stringhe s): 64.000 metodo chiamate/sec

Anche se capisco la pena di prestazioni tra 2 e 3 (serializzazione), io davvero non capisco per questo che sono 100 volte più lento da caso a caso 1 2 . A mio avviso, una volta creato il proxy, tutte le successive invocazioni del metodo devono essere molto veloci poiché nessun dato viene eseguito il marshalling da un AppDomain all'altro. Qualcuno ora perché comunicare tra AppDomain è così lento? Sto facendo qualcosa di sbagliato?

PS1. L'unico suggerimento che ho su questo è here: "E il costo di attraversare un confine AppDomain è imbarazzante.". Immagino che si riferisca alla serializzazione ...

PS2. Non conteggio del tempo di creazione AppDomain o Proxy (i miei benchmark iniziano nel primo richiamo del metodo)

PS3. Sto usando .NET 3.5 in una macchina WinXP SP3. Ho anche provato .NET 4.0 Beta 1 senza differenze significative.

risposta

11

Se si contano le linee di IL coinvolte in ogni scenario, si vedrà che il CLR sta facendo molto più di 100 volte il lavoro durante i servizi remoti. Un'invocazione diretta è solo pochi opcode, ma con il remoting ci sono più classi coinvolte, proxy reali/trasparenti, controlli di sicurezza, serializzazione, yadda yadda yadda. Avrai bisogno di affrontarlo attraverso il design - non esiste una bacchetta magica per migliorare il perfezionamento attraverso l'implementazione.

+1

+1 Sono d'accordo con te completamente. Una semplice chiamata al metodo diretto è estremamente semplice. Una chiamata di metodo attraverso ** remoting ** è molto più pesante. Il sovraccarico è molto più grande. L'unica vera soluzione è una buona progettazione dell'applicazione che non dipenda dalla velocità della comunicazione cross AppDomain. – jpbochi

1

C'è un modo per chiamare un singolo metodo di supporto che richiede parametri su quante volte si desidera chiamare il metodo necessario? Le prestazioni delle chiamate Cross-AppDomain variano notevolmente in base all'implementazione. Credo che potrebbe essere significativamente migliore nel CLR 4.0, ma non sono completamente esperto nei dettagli.

In generale, tuttavia, si desidera evitare il sovraccarico "raggruppando" le chiamate attraverso un metodo di supporto.

+0

Non vedo come mi aiuterà. Il metodo della mia classe A fa esattamente questo: chiamata continua object.MyMethod().Se il costo di una chiamata in un proxy è veramente 100 volte più grande di una chiamata su uno stesso oggetto AppDomain, l'impatto sul mio progetto sarà enorme. – Yiannis

+3

Call object.MyHelperMethod, che chiama object.MyMethod ripetutamente nell'altro AppDomain. Se hai bisogno delle prestazioni e hai presupposto/richiesto cross-AppDomain ad alta velocità, le chiamate per questo, allora sì, potrebbero avere un grande impatto sul tuo design. –

+0

Ohh, vedo ..! :-) OK, questo ovviamente renderà le cose veloci. Ma questo esempio è solo un giocattolo, il mio vero programma non chiamerà la stessa funzione 20mil volte al secondo ..! Dovrò effettuare varie chiamate cross-AppDomain che devono essere veloci in generale. Thnanks comunque! – Yiannis

0

Ho visto gli stessi risultati. Non riesco a spiegare perché è molto più lento, tranne che è più veloce di avere due processi diversi in esecuzione e in comunicazione tra loro. Nel mio progetto mi sono trovato di fronte a un dilemma simile. Alla fine, ho modificato il mio design per creare domini di app indipendenti; il dominio dell'app è stato in grado di svolgere il proprio lavoro senza la necessità di comunicare con un altro dominio dell'app durante l'esecuzione ... alla fine completerebbe i dati.

Problemi correlati