2009-08-29 16 views
12

Sto leggendo il libro di Bill Wagner Effective C#. Nell'articolo 32 sta sostenendo che gli sviluppatori possano creare assemblaggi più piccoli e più coesi che possano essere riutilizzati più facilmente. Tuttavia, nello stesso articolo, dice:Prestazioni cross-assembly .NET Hit

... I controlli di sicurezza aggiuntivi sono anche eseguiti attraverso i limiti dell'assieme. Tutto il codice dallo stesso assembly ha lo stesso livello di attendibilità (non necessariamente gli stessi diritti di accesso, ma lo stesso livello di verità). Il CLR esegue alcuni controlli di sicurezza ogni volta che il flusso di codice attraversa un confine . Il minor numero di volte che il tuo flusso del programma attraversa montaggio confini, più efficiente sarà essere ... Nessuna di queste prestazioni preoccupazioni dovrebbero dissuadere dal rompere assemblee che sono troppo grande. Le penalità per le prestazioni sono pari a minori.

La mia domanda è ci sono controlli di sicurezza extra eseguiti per ogni chiamata di metodo in Foo.dll, o solo la prima volta che viene caricato l'assembly?

Grazie

+0

@Andrew: Fatto. – dewald

risposta

12

Il sistema di sicurezza in .NET è piuttosto complesso. Non sono sicuro che la risposta sia così semplice come potrebbe sembrare a prima vista. Anche nel caso in cui si disponga di un singolo assieme, i controlli di sicurezza vengono comunque eseguiti. Quando si avvia un'applicazione che ha tutta la logica in un singolo exe, non si ignorano i controlli di sicurezza .NET per il caricamento e la verifica degli assembly, né si ignorano i controlli di ereditarietà dei tipi. Tuttavia, una volta verificata la sicurezza per un dato ambito, di solito non si verifica più (potrebbero esserci alcune circostanze attenuanti che costringerebbero nuovamente la verifica delle prove.)

Gli assembly multipli non si comportano in modo diverso. Potrebbero esserci alcuni costi aggiuntivi per il carico di montaggio e il costo di accesso al tipo iniziale, poiché ogni nuovo assembly richiederà quei controlli di sicurezza iniziali. Tuttavia, tali verifiche generalmente impallidiscono rispetto al processo di JITting del codice stesso.

Oltre al carico dell'assembly di base e alle verifiche di sicurezza del tipo, è possibile che siano richieste esplicite autorizzazioni. Gli spazi dei nomi di sistema di Microsofts sono pieni di controlli di sicurezza Demand e LinkDemand che verificano che tutti i chiamanti in cima allo stack (richiesta) o il chiamante immediato (richiesta di collegamento) dispongano dell'autorizzazione per effettuare la chiamata. (Il codice dovrebbe anche includere tali controlli erano appropriati per convalidare i chiamanti hanno l'autorizzazione appropriata, anche.) Questi controlli di sicurezza avverranno indipendentemente da dove risiede il codice ... localmente, in un altro assembly, o anche in un assembly in un altro dominio di app . Tuttavia, una volta entrati in chiamate fatte ad altri domini o processi di app, o anche a servizi e altri server, l'overhead di effettuare il marshalling di tali chiamate e di effettuare connessioni è di ordine di grandezza più costoso.

Questo non è nemmeno l'intero quadro quando si tratta di sicurezza .NET. Alcuni controlli di sicurezza sono più costosi di altri. Alcuni richiedono credenziali, altri richiedono prove, ecc. La sicurezza non è qualcosa che si può sottrarre ... è una componente essenziale e critica del moderno sviluppo del software. Non mi preoccuperei molto del costo della sicurezza ... poiché è ben implementato e ottimizzato in .NET framework e CLR. Vorrei fare il possibile per garantire che la tua applicazione sia adeguatamente progettata e organizzata.Se la separazione del codice in più assiemi è logica, riduce la manutenzione, la distribuzione e lo sforzo di refactoring, quindi il suo WELL vale il piccolo costo aggiuntivo per la sicurezza.

4

Quei controlli di sicurezza sono fatte quando il CLR carica l'assembly. Una volta caricato il gruppo, non sono necessari ulteriori controlli di sicurezza.

4

Ho anche letto il passaggio nel libro di Bill Wagner e aveva gli stessi dubbi circa le prestazioni, così ho benchmark l'applicazione che stiamo sviluppando attualmente:

ci sono poche centinaia di migliaia fino a 3-4 milioni di chiamate a una delle nostre classi C#.

Non fa alcuna differenza se questa classe si trova nello stesso assieme o in un altro assieme, purché si trovino sulla stessa macchina nello stesso processo e dominio. Non sono riuscito a misurare nessuna penalità significativa per le prestazioni!

Ovviamente, se è necessario effettuare il marshalling delle chiamate, le cose cambiano. Forse molto diverso ...