Perché non utilizzare il codice di sicurezza non gestito in C #

10

C'è un'opzione in C # per eseguire il codice deselezionato. In genere non è consigliabile farlo, poiché il codice gestito è molto più sicuro e supera molti problemi.

Tuttavia mi chiedo, se sei sicuro che il tuo codice non causerà errori, e sai come gestire la memoria, allora perché (se ti piace il codice veloce) segui il consiglio generale?

Mi sto chiedendo questo da quando ho scritto un programma per una videocamera, che richiedeva una manipolazione bitmap estremamente veloce. Anch'io ho realizzato alcuni algoritmi grafici veloci e funzionano perfettamente con le bitmap usando codice non gestito.

Ora mi chiedo in generale, se sei sicuro di non avere perdite di memoria o rischi di arresto anomalo, perché non utilizzare il codice non gestito più spesso?

PS my background: Mi sono trasferito in questo mondo di programmazione e lavoro da solo (lo faccio per alcuni anni) e quindi spero che questa domanda sul design del software non sia poi così strana. Non ho davvero altre persone là fuori come un insegnante per chiedere queste cose.

    
posta user613326 03.12.2012 - 19:50
fonte

4 risposte

27

Bene, si tratta principalmente del vecchio adagio

  • Non ottimizzare
  • (solo per esperti) Non ottimizzare ancora

Ma in realtà posso pensare a tre ragioni principali per evitare codice non sicuro.

  1. Bugs : La parte critica della tua domanda è "se sei sicuro che il tuo codice non causerà errori". Bene, come puoi essere assolutamente sicuro? Hai usato un dimostratore con un metodo formale che garantiva il tuo codice corretto? Una cosa è certa nella programmazione, e cioè che avrai dei bug. Quando togli una sicurezza, permetti a nuovi tipi di insetti di scivolare verso il basso. Quando lasci che il garbage collector si prenda cura della memoria per te, molti problemi vanno via.

  2. Non sempre veloce come credi : l'altro punto è: a seconda del problema, il guadagno potrebbe non essere così grande. Anche se non riesco a trovarli in questo momento, ricordo uno studio di Google che confrontava la velocità di Java, Scala, Go e C ++. Una volta ottimizzato a terra, ovviamente il C ++ era molto più veloce. Ma l'algoritmo programmato in modo "idiomatico" non era molto più veloce. Idiomatico nel senso che stavano usando la struttura e gli idiomi standard (stl container, no loop srotolato, ecc.). Microsoft ha fatto un esperimento simile con C # e C ++. Raymond Chen, uno dei migliori ingegneri di Microsoft, ha dovuto scrivere la propria implementazione di std :: string per battere C #. (vedi: link ) Per molto meno sforzo, hai prestazioni discrete nel codice gestito, quindi spesso non vale la pena.

  3. Riutilizzabilità : il codice non sicuro può essere utilizzato solo in un ambiente di trust completo. Ad esempio, in un server ASP.NET, di solito non è possibile utilizzare codice non sicuro, poiché sarebbe piuttosto facile introdurre una vulnerabilità tramite l'overflow del buffer. Un altro esempio potrebbe essere clickonce. O se l'applicazione è stata letta da una condivisione di rete. Quindi, se prevedi di utilizzare il tuo codice in una varietà di scenari di distribuzione, il codice non sicuro è fuori dal gioco.

Quindi in pratica: è disapprovato perché potrebbe introdurre bug non necessari, potrebbe non avere alcun vantaggio e ridurre la riusabilità del tuo codice.

Ma se il tuo scenario lo richiede realmente per le prestazioni (e hai dati per dimostrarlo), sei un programmatore esperto che sa come gestire la memoria e il tuo codice sarà usato in un ambiente controllato, quindi sicuro, vai a prenderlo .

    
risposta data 03.12.2012 - 20:42
fonte
4

In un certo senso, il codice non gestito è una forma di pagamento: acquisti l'esecuzione più veloce con lo sforzo di sviluppo extra. In effetti, il codice non gestito richiede più tempo per lo sviluppo, il debug e la manutenzione. Il modo giusto per farlo è una sfida per la maggior parte dei partecipanti. In un certo senso, è simile alla programmazione in assembly: certo, puoi spremere più energia dalla tua CPU se scrivi in assembly * , ma "spendi" molto più impegno per quella rotta.

A volte, la differenza nei tempi di sviluppo è molto significativa - giorni invece di ore. Tuttavia, la differenza nella velocità di esecuzione non è così drammatica. Questo è il motivo per cui lo sviluppo di codice non gestito è riservato a situazioni simili a quelle che hai descritto nelle tue implementazioni post-localizzate e autoconfinate di algoritmi assetati di risorse, come l'elaborazione audio e video.

Essenzialmente, la risposta alla tua domanda è simile alla risposta del perché non tutti guidano la Ferrari: è un'auto molto migliore, giusto? (Un) per fortuna, non tutti possono permetterselo.

* I progressi degli ultimi decenni nella tecnologia di ottimizzazione dei compilatori hanno ridotto questo gap così tanto che non è più una scommessa sicura.     
risposta data 03.12.2012 - 22:00
fonte
0

Perché essere "sicuri" della correttezza o di qualsiasi altro vincolo in senso matematico (cioè tu hai una prova) è un problema molto difficile per le lingue imperative. I programmi hanno spesso un numero così elevato di stati che non è possibile verificarli anche controllando ogni possibile stato. E creare una dimostrazione costruttiva non è qualcosa che puoi automatizzare.

Quindi la ragione è che le assicurazioni che l'esecuzione gestita fornisce il più delle volte sovrastimano il piccolo guadagno di prestazioni che otterresti con codice non sicuro. Naturalmente, questo dipende anche dal caso d'uso specifico.

    
risposta data 03.12.2012 - 19:58
fonte
0

In breve, nulla ti impedisce di fare tutto ciò che funziona e di gestire i bit e i bulloni del tuo programma in ambiente C ++. Siccome sei abbastanza sicuro di poter gestire correttamente tutti gli anelli di memoria e le perdite senza garbage collector, allora sei il benvenuto in C ++ :)

Al contrario, C # offre vantaggi che offrono ambiente di sviluppo sicuro / gestito e strongmente tipizzato per funzionare in sicurezza in .NET framework.

L'eventuale back-draw di programmazione di codice non gestito è il tempo di sviluppo più lungo, l'allocazione di tempo per i test dettagliati. Ovviamente aumenterai la velocità di elaborazione e un maggiore controllo del funzionamento del tuo software.

Pertanto, l'opzione per lavorare con il codice non gestito in .NET Framework a partire dalla 4.0 è un'opzione per casi limite quando si è sicuri che potrebbe farti guadagnare rispetto a non utilizzarlo ...

    
risposta data 03.12.2012 - 23:35
fonte

Leggi altre domande sui tag