Подтвердить что ты не робот

Альтернатива boost:: lexical_cast

Я принимаю участие в вызове, и просто для того, чтобы сократить до предела, в одном из мест в моей программе мне нужно преобразовать строку в целое. Я пробовал boost:: lexical_cast, но, к сожалению, это sooo sloowwww. Я полагаю, что все проверки, которые он выполняет. Мне нужно что-то такое, что бы выполнить это преобразование без каких-либо проверок (я знаю, что будут действительные числа, сохраненные как строки). Кстати, используя stringstream наивным образом:

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

еще медленнее, чем boost:: lexical_cast.
Есть ли альтернатива??

4b9b3361

Ответ 1

Вы можете сделать это с помощью sscanf, но я подозреваю, что он медленнее, чем atoi, поскольку он обрабатывает локали.

Вам определенно будет интересно прочитать этот С++ Convert String to Int Speed ​​, в котором реализована наивная реализация, которая быстрее, чем atoi.

EDIT: другое сообщение, сравнивающее различные строки с реализациями int: С++ String to Int.

Ответ 2

Я могу порекомендовать Boost Spirit (разобрать с Qi):

.

#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 С++ 98)
  • Boost Spirit (выше)
  • Последовательность обновления

Эта публикация содержит контрольные показатели

Ответ 3

В 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);

Обратите внимание, что он по-прежнему работает, но должен быть достаточно стабильным на практике. Если возникнут какие-либо проблемы, сообщите мне.

Ответ 4

strtol может быть лучше atoi (в частности, обработка ошибок w.r.t.) и будет быстрее, чем lexical_cast.

Ответ 5

Функции atoi/itoa обычно быстрее, как и sscanf().

Все это из среды выполнения c, но они должны хорошо работать для вас.

Ответ 6

Если вам действительно не нужно делать какие-либо проверки, самым быстрым способом может быть преобразование строки самостоятельно. Я имею в виду что-то вроде этого:

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

Ответ 7

как насчет использования stoi(). Я уверен, что он должен быть достаточно быстрым, чтобы удовлетворить ваши потребности.