Pourquoi ne pas utiliser un code sécurisé non managé en C #

10

Il y a une option en C # pour exécuter du code non coché. Il n'est généralement pas conseillé de le faire, car le code managé est beaucoup plus sûr et résout de nombreux problèmes.

Cependant, je me demande, si vous êtes sûr que votre code ne causera pas d'erreurs et que vous savez comment gérer la mémoire, alors pourquoi (si vous aimez le code rapide) suivez les conseils généraux?

Je me le demande depuis que j'ai écrit un programme pour une caméra vidéo, qui a nécessité une manipulation bitmap extrêmement rapide. J'ai moi-même créé des algorithmes graphiques rapides, et ils fonctionnent très bien sur les bitmaps en utilisant du code non managé.

Maintenant, je me demande en général, si vous êtes sûr de ne pas avoir de fuites de mémoire ou de risques de plantages, pourquoi ne pas utiliser plus souvent du code non managé?

PS mon expérience: je suis un peu entré dans ce monde de la programmation et je travaille seul (je le fais depuis quelques années) et j'espère donc que cette question de conception de logiciels n'est pas si étrange. Je n'ai pas vraiment d'autres personnes comme un enseignant pour demander de telles choses.

user613326
la source
8
unsafesignifie «sachez ce que vous faites et pesez les avantages par rapport aux risques». J'ai utilisé unsafeune poignée de fois, et c'était toujours pour quelque chose de très spécifique lié à la performance qui pouvait être bloqué dans sa propre méthode. Je ne l'utilise pas comme technique de programmation générale, car la plupart du temps, l'avantage supplémentaire en termes de performances ne vaut pas la perte de sécurité.
Robert Harvey
14
J'ai écrit beaucoup de code au fil des ans qui s'est parfois écrasé ou a eu des fuites de mémoire, que j'étais à peu près sûr qu'il n'y avait pas de fuites de mémoire ou de risques de plantages.
whatsisname
1
Voici un bon unsafeexemple de cas d'utilisation: stackoverflow.com/q/11660127/102937
Robert Harvey
3
Je suppose que votre code bitmap contient encore des bogues, mais vous ne les avez tout simplement pas détectés. Et même si ce n'est pas le cas, attendez d'avoir à implémenter de nouvelles exigences dans le code existant.
Doc Brown
1
Parce que même lorsque vous êtes sûr que votre code ne causera pas d'erreurs, il provoquera toujours des erreurs.
user253751

Réponses:

27

Eh bien, c'est surtout un adage séculaire

  • Ne pas optimiser
  • (réservé aux experts) Ne pas optimiser encore

Mais en fait, je peux penser à trois raisons principales pour éviter le code dangereux.

  1. Bugs : La partie critique de votre question est "si vous êtes sûr que votre code ne provoquera pas d'erreurs". Eh bien, comment pouvez-vous être absolument totalement sûr? Avez-vous utilisé un prouveur avec une méthode formelle qui garantissait que votre code était correct? Une chose est sûre en programmation, c'est que vous aurez des bugs. Lorsque vous enlevez une sécurité, vous autorisez de nouveaux types de bogues à s'infiltrer. Lorsque vous laissez le garbage collector s'occuper de la mémoire pour vous, beaucoup de problèmes disparaissent.

  2. Pas toujours aussi vite que vous le pensez : L'autre point est: selon le problème, le gain peut ne pas être si grand. Bien que je n'arrive pas à les trouver en ce moment, je me souviens d'une étude de Google comparant la vitesse de Java, Scala, Go et C ++. Une fois optimisé au sol, le C ++ était bien sûr beaucoup plus rapide. Mais l'algorithme programmé de manière "idiomatique" n'était pas vraiment beaucoup plus rapide. Idiomatique dans le sens où ils utilisaient une structure et des idiomes standard (conteneur stl, pas de boucle déroulée, etc.). Microsoft a fait une expérience similaire avec C # et C ++. Raymond Chen, l'un des meilleurs ingénieurs de Microsoft, a dû écrire sa propre implémentation de std :: string pour battre C #. (voir: http://www.codinghorror.com/blog/2005/05/on-managed-code-performance-again.html) Pour beaucoup moins d'efforts, vous avez obtenu des performances assez décentes dans le code managé, donc cela ne vaut souvent pas la peine.

  3. Réutilisation : le code dangereux ne peut être utilisé que dans un environnement de confiance totale. Par exemple, dans un serveur ASP.NET, vous ne pouvez généralement pas utiliser de code non sécurisé, car il serait assez facile d'introduire une vulnérabilité par débordement de tampon. Un autre exemple serait clickonce. Ou si votre application a été accessible à partir d'un partage réseau. Donc, si vous prévoyez d'utiliser votre code dans une variété de scénarios de déploiement, le code non sécurisé est hors jeu.

Donc, fondamentalement: il est mal vu car il peut introduire des bogues inutiles, il peut très bien être sans gain du tout, et il réduit la réutilisabilité de votre code.

Mais si votre scénario l'exige vraiment pour les performances (et que vous avez des données pour le prouver), vous êtes un programmeur expérimenté qui sait gérer la mémoire et votre code sera utilisé dans un environnement contrôlé, alors allez-y.

Laurent Bourgault-Roy
la source
4

D'une certaine manière, le code non managé est une forme de paiement: vous achetez une exécution plus rapide avec l'effort de développement supplémentaire. En effet, le code non managé nécessite plus de temps pour se développer, déboguer et maintenir. Bien faire les choses est un défi pour la plupart des participants. D'une certaine manière, cela est similaire à la programmation en assembleur: bien sûr, vous pouvez extraire plus de puissance de votre CPU si vous écrivez en assembleur * , mais vous "dépensez" beaucoup plus d'efforts dans cette voie.

Parfois, la différence de temps de développement est très importante - des jours au lieu d'heures. Cependant, la différence de vitesse d'exécution n'est pas aussi spectaculaire. C'est pourquoi le développement de code non managé est réservé à des situations similaires à celle que vous avez décrite dans votre post - implémentations localisées et autonomes d'algorithmes gourmands en ressources, tels que le traitement audio et vidéo.

Essentiellement, la réponse à votre question est similaire à celle de savoir pourquoi tout le monde ne conduit pas Ferrari: c'est une bien meilleure voiture, non? (Malheureusement), tout le monde ne peut pas se le permettre.


* Les progrès des dernières décennies dans la technologie d'optimisation des compilateurs ont tellement réduit cet écart que ce n'est plus un pari sûr.

dasblinkenlight
la source
0

Parce qu'être «sûr» de l'exactitude ou de toute autre contrainte au sens mathématique (c'est-à-dire que vous avez des preuves) est un problème très difficile pour les langages impératifs. Les programmes ont souvent un nombre d'états tellement élevé qu'il n'est pas possible de les vérifier même en vérifiant chaque état possible. Et créer une preuve constructive n'est pas quelque chose que vous pouvez automatiser.

La raison en est que les assurances que l'exécution gérée fournit le plus souvent surestiment le petit gain de performances que vous obtiendriez avec un code dangereux. Bien sûr, cela dépend aussi du cas d'utilisation spécifique.

Tamás Szelei
la source
1
Je ne pense pas que cela ait quoi que ce soit à voir avec l'exactitude ou la simplicité de raisonner ..
Jimmy Hoffa
Personne ne parle d'une preuve formelle de correction.
1
Je suis sûr que votre message manque le sujet, mais je ne formule pas de preuve formelle. De même, je peux être sûr que mon programme est correct (par exemple, après des tests approfondis, un débogage et une utilisation prolongée dans le monde réel sans aucun bogue) sans le prouver une fois pour toutes. Cette interprétation est beaucoup plus proche de ce que la plupart des gens veulent dire quand ils disent "c'est correct". Les méthodes formelles sont une préoccupation très spécifique et totalement hors de considération pour la plupart des développeurs.
1
Je ne vois pas une telle question. La question, telle que je l'ai lue, est de savoir pourquoi la trappe d'échappement du monde managé n'est pas / ne devrait pas être utilisée plus souvent (ce qui implique que la valeur par défaut du code managé est logique). Dans tous les cas, si vous voulez répondre à cette question (en soulignant la dureté de garantir l'exactitude), vous pouvez le faire sans parler d'une assurance formelle absolue et correcte. Votre réponse tourne désormais uniquement autour de preuves sonores complètes et correctes pour les langues impératives. Mais c'est exagéré, et je pense que les preuves concernant le C # géré sont également (ou presque) difficiles.
1
@fish: Je peux voir ce que vous dites. Il y a une corrélation entre quelque chose qui est difficile à prouver et quelque chose qui est difficile à raisonner. S'il est difficile de prouver que c'est correct, alors il est très probablement difficile d'être sûr que c'est vrai.
Michael Shaw
0

En bref, rien ne vous empêche de faire tout ce travail et de gérer les bits et les boulons de votre programme dans un environnement C ++. Comme vous êtes à peu près sûr que vous pouvez gérer correctement tous les cerceaux et fuites de mémoire sans garbage collector, vous pouvez le faire en C ++ :)

Au contraire, C # présente des avantages en fournissant un environnement de développement sûr / géré et fortement typé pour s'exécuter en toute sécurité dans le cadre .NET.

Le retrait possible de la programmation de code non géré est le temps de développement plus long, l'allocation de temps pour des tests détaillés. Vous gagnerez bien sûr la vitesse de traitement et plus de contrôle sur le fonctionnement de votre logiciel.

Ainsi, l'option de travailler avec du code non géré dans .NET Framework à partir de 4.0 est une option pour les cas marginaux lorsque vous êtes sûr que cela pourrait vous apporter des gains par rapport à ne pas l'utiliser ...

Yusubov
la source
Aha c'est intéressant, vous voyez, je viens du monde des microcontrôleurs et là on écrit généralement du c ++ décent, il y a peu de place pour l'erreur et une bonne conception du logiciel est la chose clé à faire
user613326