簡體   English   中英

boost :: lexical_cast的替代品

[英]Alternative to boost::lexical_cast

我正在參與挑戰,只是為了切入點,在我的程序中的一個地方我需要將字符串轉換為整數。 我已經嘗試過boost :: lexical_cast,但不幸的是它是sooo sloowwww。 我想因為它執行的所有檢查。 我需要的是能夠在沒有任何檢查的情況下執行此轉換的內容(我知道將有效數字存儲為字符串)。 順便使用stringstream以天真的方式:

stringstream interpreter;
interpreter << str;
interpreter >> number;

甚至比boost :: lexical_cast慢。
atoi是唯一的選擇嗎?

你可以使用sscanf來做,但我懷疑它比atoi處理語言環境要慢。

你肯定會有興趣閱讀這個C ++ Convert String to Int Speed基准測試,它具有比atoi更快的天真實現。

編輯:另一篇文章將不同的字符串與int實現進行比較: C ++ String to Int

我可以推薦Boost Spirit(用Qi解析):

  1. 一些基准
  2. 另請參閱我的其他答案atoi上有很多整數的字符數組
  3. 一些樣本用途:

#include <boost/spirit/include/qi.hpp>

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<int> 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<int> 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;
}

其他

請務必查看二進制(反)序列化IFF,您可以指定流(文本)格式。 請參閱我最近的答案以便比較針對序列化/反序列化的方法:

  • STL(簡單的ANSI C ++ 98標准庫)
  • 提升精神(上圖)
  • 提升序列化

那篇文章包括基准

對於Google Summer of Code,我正在開發一個新的Boost庫來解決這個問題。 可以在這里找到的boost :: coerce。 后端以boost :: spirit為基礎,通過更簡單的界面為您提供所有優勢(特別是速度):

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

要么

std::string s = boost::coerce::as<std::string>(23);

請注意,它仍在進行中,但在實踐中應該足夠穩定。 如果出現任何問題,請告訴我。

strtol可以是更好的atoi(特別是wrt錯誤處理),並且比lexical_cast更快。

atoi / itoa函數通常更快,sscanf()也是如此。

所有這些都來自c運行時,但它們應該適合你。

如何使用stoi()。 我確信它必須足夠快以滿足您的需求。

如果你真的不需要做任何檢查,最快的方法就是自己轉換字符串。 我的意思是編碼這樣的代碼:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM