Question

J'ai entendu dire la gestion des exceptions est un peu coûteux en raison du déroulement de la pile.

Je ne comprends pas quelque chose, le déroulement de la pile se produit si je jette une exception et si je l'utilise « retour ». Alors, où est la différence?

Si, par exemple, je reçois un problème de mémoire que je ne peux pas gérer - la seule option est d'arrêter la fonction jusqu'à ce que le j'atteint l'endroit où le problème doit être manipulé ou notifié. Alors, quel est mon autre choix pour lancer une exception?

Je peux utiliser « retourner » au lieu de jeter exception, mais il est le même. Je sais pile déroulage peut aller encore six piles en arrière, mais de vérifier si la valeur de retour et « retour » combiné.

Une explication sera la bienvenue.

Était-ce utile?

La solution

Lorsque vous utilisez un retour, la pile est « déroulé » sans condition, qui peut théoriquement être aussi simple que l'exécution d'une seule instruction de code machine « ret ». Sous des exceptions, le déroulement de la pile doit rechercher un gestionnaire d'exception appropriée, ce qui est une tâche beaucoup plus complexe. Le chemin d'exception a également la tâche de la construction et la copie sans doute l'objet d'exception, qui ne peut être trivial.

Autres conseils

déroulement de la pile est différent de simplement revenir. Cela implique aussi une recherche d'un gestionnaire d'erreurs (un bloc catch) dans chaque niveau inférieur dans la pile. C'est ce qui en fait un lourd processus.

C'est pourquoi vous ne devez utiliser que des exceptions pour des circonstances vraiment exceptionnelles. Les avertissements sur la gestion des exceptions sont pour les gens qui voient simplement une exception comme un moyen de fournir des données plus haut dans la pile; les gens qui aiment faire de la programmation « intelligente ». Ils pensent que c'est une façon intelligente de contourner un problème, mais ils créent de nouveaux problèmes au lieu de deux, ils n'avaient pas prévu.

En général, vous êtes mieux utiliser les exceptions (pour des circonstances vraiment exceptionnelles) plutôt que des codes de retour, car cela rend votre code plus facile à lire et à maintenir. Par exemple, ce qui est plus facile à lire et à maintenir?

void MyMethod()
{
    try
    {
        Method1(); 
        Method2();
        Method3();
    }
    catch(SomeException const & e) // edited per Mordachai's suggestion
    {
       // handle SomeException
    }
    catch(SomeOtherException const & e)
    {
       // handle SomeOtherException
    }
}

void MyMethod()
{
    int err;
    err = Method1();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
    err = Method2();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
    err = Method3();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
}

La vitesse des mécanismes de gestion des erreurs dans le cas d'une erreur est sans importance - ils doivent être exécutés trop souvent pour avoir un impact sur les performances du programme dans son ensemble (ils sont exceptionnelle événements)

Quand les gens parlent de la gestion des exceptions étant coûteux dont ils parlent l'effet qu'elle a sur la performance d'une fonction lorsque cette fonction se termine sans soulever une exception . De nombreux compilateurs réduisent cette surcharge à près de zéro -. Mais il y a certaines plates-formes, notamment les consoles de jeux, où soit les compilateurs disponibles ou le matériel ne traite pas des exceptions très bien

Il y a un petit « coût » pour l'infrastructure nécessaire pour transmettre des exceptions en premier lieu. Cette habitude d'être assez important beaucoup de gens ont choisi de l'éviter et désactiver RTTI tout à fait. Ces jours-ci il est si négligeable que si sa question que peut-être C ++ est déjà trop haut niveau pour vous; -)

En ce qui concerne la propagation des exceptions et la pile dérouleur il y a des coûts supplémentaires, mais depuis (a) que vous auriez à dérouler la pile de toute façon, comme vous le dites (bien que ce n'est pas vraiment où le coût est) et (b) vous êtes déjà sur un chemin d'exception où le coût supplémentaire est probablement jamais un problème de toute façon.

La plupart des gens qui se plaignent au sujet des coûts de gestion des exceptions pensent de la façon dont il était.

Si vous êtes intéressé par la gestion des exceptions d'impact sur les performances, le meilleur endroit pour commencer à lire est le Rapport technique sur Performance C (chapitre 5.4 en particulier).

Je suggère la concentration sur la qualité, l'exactitude et la robustesse avant de se soucier de la performance d'un programme. De nombreux utilisateurs préféreraient un programme de travail lent à un rapide que les défauts souvent.

Une fois le programme fonctionne, exécutez un profileur et savoir où la plupart du temps est passé. Mon humble avis est que la gestion des erreurs peut prendre un peu plus, car il arrive moins souvent.

La plupart des versions de la gestion des exceptions ajoutent quelques petits frais généraux supplémentaires pour aider l'accord compliler avec des questions telles que la portée. est un article qui a une explication. Les frais généraux dont nous parlons est très faible et presque jamais se soucier de la valeur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top