Combien coûtent les exceptions en C #? Il semble qu’ils ne soient pas incroyablement coûteux tant que la pile n’est pas profonde; Cependant, j'ai lu des rapports contradictoires.
Y a-t-il un rapport définitif qui n'a pas été réfuté?
Combien coûtent les exceptions en C #? Il semble qu’ils ne soient pas incroyablement coûteux tant que la pile n’est pas profonde; Cependant, j'ai lu des rapports contradictoires.
Y a-t-il un rapport définitif qui n'a pas été réfuté?
Jon Skeet a écrit des Exceptions et de la Performance dans .NET en janvier 2006
Qui a été mis à jour Exceptions et les Performances Redux (merci @Gulzar)
Pour ce qui Rico Mariani de renchérir le Coût réel de La .NET Exceptions -- Solution
Également de référence: Krzysztof Cwalina - lignes Directrices de Conception de mise à Jour: Exception Jeter
Ayant lu que les exceptions sont coûteuses en termes de performance, j'ai jeté un simple programme de mesure, très semblable à celui de Jon Skeet publiée il y a des années. J'en parle ici principalement à fournir des chiffres mis à jour.
Il a fallu le programme ci-dessous 29914 millisecondes pour traiter un million d'exceptions, qui s'élève à 33 exceptions par milliseconde. C'est assez rapide à faire des exceptions une alternative viable aux codes de retour pour la plupart des situations.
Veuillez noter, cependant, que avec les codes de retour au lieu d'exceptions près le même programme s'exécute en moins d'une milliseconde, ce qui signifie que les exceptions sont à moins de 30 000 fois plus lent que les codes de retour. Comme l'a souligné Rico Mariani ces numéros sont également le nombre minimum de participants. Dans la pratique, lancer et attraper une exception prendra plus de temps.
Mesurée sur un ordinateur portable avec processeur Intel Core 2 Duo T8100 @ 2,1 GHz avec .NET 4.0 en version release pas s'exécuter sous le débogueur (ce qui serait beaucoup plus lent).
C'est mon code de test:
static void Main(string[] args)
{
int iterations = 1000000;
Console.WriteLine("Starting " + iterations.ToString() + " iterations...\n");
var stopwatch = new Stopwatch();
// Test exceptions
stopwatch.Reset();
stopwatch.Start();
for (int i = 1; i <= iterations; i++)
{
try
{
TestExceptions();
}
catch (Exception)
{
// Do nothing
}
}
stopwatch.Stop();
Console.WriteLine("Exceptions: " + stopwatch.ElapsedMilliseconds.ToString() + " ms");
// Test return codes
stopwatch.Reset();
stopwatch.Start();
int retcode;
for (int i = 1; i <= iterations; i++)
{
retcode = TestReturnCodes();
if (retcode == 1)
{
// Do nothing
}
}
stopwatch.Stop();
Console.WriteLine("Return codes: " + stopwatch.ElapsedMilliseconds.ToString() + " ms");
Console.WriteLine("\nFinished.");
Console.ReadKey();
}
static void TestExceptions()
{
throw new Exception("Failed");
}
static int TestReturnCodes()
{
return 1;
}
Je suppose que je suis dans le camp que si les performances des exceptions ont une incidence sur votre demande puis vous lancez FAÇON beaucoup trop. Les Exceptions doivent être pour des conditions exceptionnelles, pas de routine de gestion d'erreur.
Cela dit, mon souvenir de la façon dont les exceptions sont gérées essentiellement à pied jusqu'à la pile de trouver une instruction catch qui correspond au type de l'exception levée. De sorte que les performances seront les plus touchées par la profondeur à laquelle vous êtes à partir de la capture, et combien d'attraper les déclarations que vous avez.
Dans mon cas, les exceptions étaient très chères. J'ai réécrit ceci:
public BlockTemplate this[int x,int y, int z]
{
get
{
try
{
return Data.BlockTemplate[World[Center.X + x, Center.Y + y, Center.Z + z]];
}
catch(IndexOutOfRangeException e)
{
return Data.BlockTemplate[BlockType.Air];
}
}
}
Dans ceci:
public BlockTemplate this[int x,int y, int z]
{
get
{
int ix = Center.X + x;
int iy = Center.Y + y;
int iz = Center.Z + z;
if (ix < 0 || ix >= World.GetLength(0)
|| iy < 0 || iy >= World.GetLength(1)
|| iz < 0 || iz >= World.GetLength(2))
return Data.BlockTemplate[BlockType.Air];
return Data.BlockTemplate[World[ix, iy, iz]];
}
}
Et remarqué une bonne augmentation de vitesse d'environ 30 secondes. Cette fonction est appelée au moins 32 000 fois au démarrage. Le code n’est pas aussi clair quant à l’intention, mais les économies réalisées sont énormes.
Les objets d'exception Barebones en C # sont assez légers; c'est généralement la possibilité d'encapsuler un InnerException
qui le rend lourd lorsque l'arborescence d'objets devient trop profonde.
En ce qui concerne un rapport définitif, je n'en connais aucun, même si un profil dotTrace sommaire (ou tout autre profileur) pour la consommation de mémoire et la vitesse sera assez facile à réaliser.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.