Exceptions et performances
Remarque
Ce contenu est réimprimé avec l’autorisation de Pearson Education, Inc. à partir des Instructions de conception d’une infrastructure : conventions, idiomes et modèles des bibliothèques réutilisables .NET, 2ème édition. Cette édition a été publiée en 2008, et le livre a été entièrement révisé dans la troisième édition. Certaines informations sur cette page peuvent être obsolètes.
Une préoccupation courante liée aux exceptions est que si des exceptions sont utilisées pour du code qui échoue régulièrement, les performances de l’implémentation seront inacceptables. Cette inquiétude est tout à fait valide. Lorsqu’un membre lève une exception, ses performances peuvent être plus lentes. Toutefois, il est possible d’obtenir de bonnes performances tout en respectant strictement les directives d’exception qui interdisent l’utilisation de codes d’erreur. Deux modèles décrits dans cette section suggèrent des façons de procéder.
❌ N’utilisez PAS de codes d’erreur en raison de craintes que les exceptions puissent affecter les performances de manière négative.
Pour améliorer les performances, il est possible d’utiliser le modèle Tester-Doer ou le modèle Try-Parse, décrits dans les deux sections suivantes.
Modèle Tester-Doer
Parfois, les performances d’un membre levant des exceptions peuvent être améliorées en le décomposant en deux. Examinons la méthode Add de l’interface ICollection<T>.
ICollection<int> numbers = ...
numbers.Add(1);
La méthode Add
lève une exception si la collection est en lecture seule. Cela peut causer un problème de performances dans les scénarios où il est attendu que l’appel de méthode échoue fréquemment. L’une des façons d’atténuer le problème consiste à tester si la collection est accessible en écriture avant d’essayer d’ajouter une valeur.
ICollection<int> numbers = ...
...
if (!numbers.IsReadOnly)
{
numbers.Add(1);
}
Le membre utilisé pour tester une condition, qui dans notre exemple est la propriété IsReadOnly
, est appelé testeur. Le membre utilisé pour effectuer une opération levant potentiellement une exception, la méthode Add
dans notre exemple, est appelé « Doer ».
✔️ CONSIDÉREZ le modèle Tester-Doer pour les membres qui peuvent lever des exceptions dans des scénarios courants afin d’éviter les problèmes de performances liés aux exceptions.
Modèle Try-Parse
Pour les API extrêmement sensibles aux performances, un modèle encore plus rapide que le modèle Tester-Doer décrit dans la section précédente doit être utilisé. Le modèle appelle à ajuster le nom du membre pour faire d’un cas de test bien défini une partie de la sémantique du membre. Par exemple, DateTime définit une méthode Parse qui lève une exception en cas d’échec de l’analyse d’une chaîne. Il définit également une méthode TryParse correspondante qui tente d’analyser, mais retourne false si l’analyse échoue et retourne le résultat d’une analyse réussie avec un paramètre out
.
public struct DateTime
{
public static DateTime Parse(string dateTime)
{
...
}
public static bool TryParse(string dateTime, out DateTime result)
{
...
}
}
Lorsque vous utilisez ce modèle, il est important de définir la fonctionnalité try en termes stricts. Si le membre échoue pour une raison autre que le try bien défini, le membre doit toujours lever une exception correspondante.
✔️ CONSIDÉREZ le modèle Try-Parse pour les membres qui peuvent lever des exceptions dans des scénarios courants afin d’éviter les problèmes de performances liés aux exceptions.
✔️ UTILISEZ le préfixe « Try » et le type de retour booléen pour les méthodes implémentant ce modèle.
✔️ FOURNISSEZ un membre levant des exceptions pour chaque membre à l’aide du modèle Try-Parse.
Portions © 2005, 2009 Microsoft Corporation. Tous droits réservés.
Réimprimé avec l’autorisation de Pearson Education, Inc. et extrait de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition par Krzysztof Cwalina et Brad Abrams, publié le 22 octobre 2008 par Addison-Wesley Professional dans le cadre de la série sur le développement Microsoft Windows.