De quelles façons les exceptions C ralentissent le code quand il n'y a pas d'exceptions lancées?

StackOverflow https://stackoverflow.com/questions/1897940

  •  19-09-2019
  •  | 
  •  

Question

J'ai lu qu'il ya certains frais généraux à l'utilisation des exceptions C pour la gestion des exceptions, par opposition à, par exemple, vérifier les valeurs de retour. Je ne parle que de frais généraux qui est engagée lorsque aucune exception est levée. Je suppose que vous devez mettre en œuvre le code qui vérifie effectivement la valeur de retour et fait la chose appropriée, quelle que soit serait l'équivalent à ce que le bloc catch aurait fait. Et, il est aussi injuste de comparer le code qui jette des objets d'exception avec 45 variables d'état à l'intérieur de code qui renvoie un entier négatif pour chaque erreur.

Je ne suis pas essayer de construire un cas pour ou contre les exceptions uniquement sur la base desquelles on pourrait exécuter plus rapidement de C. J'ai entendu quelqu'un faire le cas récemment que le code en utilisant des exceptions devrait courir aussi vite que le code basé sur les codes de retour, une fois que vous prenez en compte tout le code de comptabilité supplémentaire qui serait nécessaire pour vérifier les valeurs de retour et de gérer les erreurs. Qu'est-ce que je manque?

Était-ce utile?

La solution

Il y a un coût associé à la gestion des exceptions sur certains et plates-formes avec certains compilateurs.

A savoir, Visual Studio, lors de la construction d'une cible de 32 bits, enregistrera un gestionnaire dans toutes les fonctions qui a des variables locales avec destructor non trivial. En gros, il met en place un gestionnaire de try/finally.

L'autre technique, utilisée par gcc et Visual Studio ciblage 64 bits, seulement augmente le temps système lorsqu'une exception est jeté (la technique consiste à traverser la pile d'appel et de consultation de table). Dans les cas où les exceptions sont rarement levées, cela peut effectivement conduire à un code plus efficace, que les codes d'erreur ne doivent pas être traitées.

Autres conseils

Seulement try / catch et essayer / except prendre quelques instructions pour configurer. Les frais généraux devrait généralement être négligeable dans tous les cas sauf les boucles les plus restreints. Mais vous ne seriez pas utiliser normalement try / catch / sauf dans une boucle intérieure de toute façon.

Je vous conseille de ne pas inquiéter à ce sujet, et d'utiliser un profileur au lieu d'optimiser votre code en cas de besoin.

Il est complètement mise en œuvre, mais qui dépendent de nombreuses implémentations récentes ont très peu ou pas de frais généraux de performance lorsque les exceptions ne sont pas jetés. En fait, vous avez raison. vérifier correctement les codes de retour de toutes les fonctions dans le code qui n'utilise pas des exceptions peut être plus lent que ne rien faire pour le code en utilisant des exceptions.

Bien sûr, vous devez mesurer la performance de vos exigences particulières pour être sûr.

certains frais généraux avec des exceptions (comme les autres réponses ont indiqué).

Mais vous n'avez pas beaucoup de choix de nos jours. Essayez de ne pas désactiver les exceptions dans votre projet, et assurez-vous que tout le code dépendant et les bibliothèques peuvent compiler et exécuter sans.

Travaillent-ils avec des exceptions désactivé?

laisse supposer qu'ils font! Ensuite, certains cas de référence, mais notez que vous devez définir un « désactiver exceptions » compilation commutateur. Sans ce commutateur, vous avez toujours la tête - même si le code ne lève jamais exceptions

.

Seuls les frais généraux est ~ 6 instructions qui ajoutent 2 SEH au début de la fonction et les laisser à la fin. Peu importe combien essayer / les prises que vous avez dans un fil, il est toujours le même.

En outre ce qui est ceci au sujet des variables locales? J'entends des gens se plaindre toujours à leur sujet lors de l'utilisation try / catch. Je ne comprends pas, parce que les déconstructeurs finiraient par être appelé de toute façon. Aussi, vous ne devriez pas laissez une exception aller jusqu'à plus de 1-3 appels.

Je pris le code de test Chip Uni et élargissions un peu. Je partage le code en deux fichiers sources (une avec des exceptions, un sans). J'ai fait chaque course de référence 1000 fois, et je clock_gettime() avec CLOCK_REALTIME pour enregistrer les heures de début et de fin de chaque itération. Ensuite, j'ai calculé la moyenne et la variance des données. J'ai couru ce test avec les versions 64 bits de g ++ 5.2.0 et 3.7.0 ++ clang sur une boîte Intel Core i7 avec 16 Go de RAM qui fonctionne ArchLinux avec le noyau 4.2.5-1-ARCH. Vous pouvez trouver le code étendu et les résultats complets .

g ++

Aucune exception
  • Moyenne: 30,022,994 nanosecondes
  • Déviation standard: 1.25327e + 06 nanosecondes
Exceptions
  • Moyenne: 30,025,642 nanosecondes
  • Déviation standard: 1.83422e + 06 nanosecondes

++ clang

Aucune exception
  • Moyenne: 20,954,657 nanosecondes
  • Ecart type: 426,662 nanosecondes
Exceptions
  • Moyenne: 23,916,638 nanosecondes
  • Déviation standard: 1.72583e + 06 nanosecondes

Les exceptions C encourent seulement une pénalité de performance non négligeable avec clang ++, et même cette pénalité est seulement ~ 14%.

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