2009-02-05 12 views
4

Mise à jour: Je vais le laisser tel quel: Le succès de la performance d'une exception (très rare) est meilleur que le succès probable de la performance pour le contrôle de chaque opération (commune)Comment puis-je tester avec élégance les situations de débordement en C#?


Je suis en train pour soutenir un « EstimatedRowCount » que dans un cas serait le produit de deux sous-curseurs qui sont reliés entre eux:

estimatedRowCount = left.EstimatedRowCount * right.EstimatedRowCount; 
return estimatedRowCount; 

Bien sûr, si gauche et à droite sont assez grands, cela jette un OverflowException.

Ici, je fais juste assez grand pour savoir si inquiète pas vraiment estimatedRowCount est précis à 100%, que ce curseur tient beaucoup de données.

En ce moment, je fais ceci:

// We multiply our rowcount 
Int64 estimRowCount = 0; 
try 
{ 
    estimRowCount = leftRowCount * rightRowCount; 
} 
catch (OverflowException) 
{ 
    // Ignore overflow exceptions 
    estimRowCount = Int64.MaxValue; 
} 

return estimRowCount; 

Y at-il une meilleure façon de tester pour les opérations de débordement, donc je ne dois pas faire l'try {} catch pour garder?

Répondre

4

Cela sonne comme un bon cas d'utilisation pour le 'unchecked' keyword.

Pour utiliser, il suffit d'envelopper votre mission dans un bloc « sans contrôle »:

Int64 estimRowCount = 0; 
unchecked 
{ 
    estimRowCount = leftRowCount * rightRowCount; 
} 

Ensuite, testez pour voir si le résultat est négatif - si elle est, il débordait:

if (estimRowCount > 0) estimRowCount = Int64.MaxValue; 

Vous Je dois m'assurer dans ce cas que ni LeftRowCount ni rightRowCount ne peuvent être négatifs, mais vu le contexte, je ne pense pas que cela se produira.

+0

Ceci est l'une de ces fonctionnalités de langage obscures que vous ne connaissez jamais jusqu'à ce que vous en ayez besoin. = P –

3

Votre solution semble tout à fait raisonnable. Y a-t-il quelque chose de particulier que vous voulez optimiser? Ce produit provoque-t-il si souvent la condition de dépassement de capacité que vous êtes préoccupé par le problème de performance lié à la gestion des exceptions?

(tout simple nourriture pour la pensée, si leftRowCount et rightRowCount sont Int32, pas Int64, votre produit ne peut pas déborder votre lvalue Int64 estimRowCount.)

+0

Tout est Int64. Et c'est probablement une "optimisation prématurée" d'apprendre d'où l'on croyait "éviter les hits pour le traitement des exceptions" si vous le pouviez. – Eli

4
 

if (Int64.MaxValue/leftRowCount <= rightRowCount) 
{ 
    estimRowCount = leftRowCount * rightRowCount 
} 
else 
{ 
    estimRowCount = Int64.MaxValue; 
} 

Je ne sais pas si je pouvais expliquer moi-même sans éditeur. Mais, j'espère que vous avez l'idée.

+0

La question est maintenant s'il serait plus efficace de vérifier pour chaque calcul que le traitement des exceptions pour les misses. – Eli

+0

Je ne suis pas sûr de ça. Mais pourquoi vous inquiétez-vous de petites choses comme celle-ci? – shahkalpesh

+0

Je suis sûr qu'il est inquiet au sujet de petites choses comme celle-ci parce que si cela est exécuté dans une boucle serrée cette petite chose devient une grande chose. Mais j'aime aussi ta suggestion. Je suis tenté de tester les deux variantes avec une minuterie de haute précision par curiosité. – JMD