Alternative au boost :: lexical_cast

Je prends part à un défi et, pour en revenir à l’essentiel, je dois convertir une chaîne en un entier dans l’un des endroits de mon programme. J’ai essayé boost :: lexical_cast mais malheureusement, c’est tellement lent! Je suppose parce que toutes les vérifications effectuées. Ce dont j’ai besoin est quelque chose qui effectuerait cette conversion sans aucune vérification (je sais qu’il y aura des nombres valides stockés sous forme de chaînes). Soit dit en passant, ssortingngstream utilise naïvement:

ssortingngstream interpreter; interpreter <> number; 

est encore plus lent que boost :: lexical_cast.
Atoi est la seule alternative?

Vous pouvez le faire en utilisant sscanf mais je suppose que c’est plus lent que atoi car il gère les locales.

Vous serez certainement intéressé par la lecture de cette référence C ++ Convert Ssortingng to Int Speed qui présente une implémentation naïve plus rapide atoi .

EDIT: Un autre article comparant différentes chaînes aux implémentations int: C ++ Ssortingng to Int .

Je peux recommander Boost Spirit (parsingr avec Qi):

  1. quelques repères
  2. Voir aussi mon autre réponse atoi sur un tableau de caractères avec beaucoup d’entiers
  3. Quelques exemples d’utilisations:

.

 #include  namespace qi = boost::spirit::qi; const char *demo1 = "1234"; const char *demo2 = "1234,2345,-777,-888"; const char *demo3 = " 1234 , 2345 , -777, -888 "; void do_demo1() { const char *begin = demo1; const char *iter = begin; const char *end = demo1+strlen(demo1); int result; if (qi::parse(iter, end, qi::int_, result)) std::cout << "result = " << result << std::endl; else std::cout << "parse failed at #" << (iter - begin) << ": " << std::string(iter, end) << std::endl; //// to allow for spaces, use phrase_parse instead of parse // if (qi::phrase_parse(begin, end, qi::int_, qi::space, result) //// ... etc } void do_demo2() { const char *begin = demo2; const char *iter = begin; const char *end = demo2+strlen(demo2); std::vector results; if (qi::parse(iter, end, qi::int_ % ',', results)) std::cout << "results = " << results.size() << std::endl; else std::cout << "parse failed at #" << (iter - begin) << ": " << std::string(iter, end) << std::endl; } void do_demo3() { const char *begin = demo3; const char *iter = begin; const char *end = demo3+strlen(demo3); std::vector results; if (qi::phrase_parse(iter, end, qi::int_ % ',', qi::space, results)) std::cout << "results = " << results.size() << std::endl; else std::cout << "parse failed at #" << (iter - begin) << ": " << std::string(iter, end) << std::endl; } int main() { do_demo1(); do_demo2(); do_demo3(); return 0; } 

Autre

Assurez-vous de regarder la (dé) sérialisation binary IFF où vous pouvez dicter le format de stream (texte). Voir ma réponse récente ici pour une comparaison des méthodes pour la sérialisation / désérialisation:

  • STL (bibliothèque standard ANSI C ++ 98 sans fioritures)
  • Renforcer l'esprit (ci-dessus)
  • Booster la sérialisation

Ce poste comprend des points de repère

Pour le Google Summer of Code, je travaille sur une nouvelle bibliothèque Boost afin de résoudre ce problème. boost :: coerce qui peut être trouvé ici . Le backend s’appuie sur boost :: spirit pour vous offrir tous ses avantages (vitesse en particulier) avec une interface beaucoup plus simple:

 int i = boost::coerce::as("23"); 

ou

 std::ssortingng s = boost::coerce::as(23); 

Notez qu’il s’agit toujours d’un travail en cours, mais qu’il devrait être suffisamment stable dans la pratique. Si des problèmes surviennent, s’il vous plaît faites le moi savoir.

strtol peut être un meilleur atoi (en particulier pour la gestion des erreurs) et sera plus rapide que lexical_cast.

Les fonctions atoi / itoa sont généralement plus rapides, tout comme sscanf ().

Tous ces éléments sont issus du runtime c, mais ils devraient bien fonctionner pour vous.

Si vous n’avez vraiment pas besoin de faire de vérifications, le moyen le plus rapide pourrait être de convertir la chaîne vous-même. Je veux dire quelque chose comme ceci:

 int integer_from(ssortingng s) { int n = 0; for (ssortingng::const_iterator it = s.begin(); it != s.end(); it++) { n = 10*n + (*it) - '0'; } return n; } 

que diriez-vous d’utiliser stoi (). Je suis sûr que cela doit être assez rapide pour satisfaire vos besoins.