Может ли кто-нибудь превзойти производительность моего целого кода std::string, связанного ниже?
Есть несколько вопросов, которые объясняют, как преобразовать целое число в std::string
в С++, например этот, но ни одно из предлагаемых решений не является эффективным.
Вот код, готовый для компиляции, для некоторых распространенных методов:
- "С++ way", используя stringstream: http://ideone.com/jh3Sa
- sprintf, которые SO-ers обычно рекомендуют для производительности: http://ideone.com/82kwR
В отличие от популярного мнения, boost::lexical_cast
имеет свою собственную реализацию (белая бумага) и не использует операторы stringstream
и числовые вставки. Мне бы очень хотелось сравнить его производительность, потому что этот другой вопрос предполагает, что это жалкое.
И мой собственный вклад, который является конкурентоспособным на настольных компьютерах, и демонстрирует подход, который работает на полной скорости и на встроенных системах, в отличие от алгоритмов, зависящих от целочисленного modulo:
- Алгоритмы Бен: http://ideone.com/SsEUW
Если вы хотите использовать этот код, я сделаю его доступным по упрощенной лицензии BSD (разрешено коммерческое использование, требуется атрибуция). Просто спросите.
Наконец, функция ltoa
является нестандартной, но широко доступной.
- версия ltoa для тех, у кого есть компилятор, который ее предоставляет (ideone не делает): http://ideone.com/T5Wim
В скором времени я опубликую свои измерения производительности.
Правила для алгоритмов
- Предоставить код для преобразования по меньшей мере 32-разрядных целых чисел без знака в десятичную.
- Вывести вывод как
std::string
. - Нет трюков, которые несовместимы с потоками и сигналами (например, статические буферы).
- Вы можете принять набор символов ASCII.
- Обязательно проверьте свой код на
INT_MIN
на двухкомпонентной машине, где абсолютное значение не представимо. - В идеале вывод должен быть символьно-символьным, идентичным канонической версии С++, используя
stringstream
, http://ideone.com/jh3Sa, но ничего это понятно, так как правильное число тоже нормально. - NEW. Хотя вы можете использовать любые параметры компилятора и оптимизатора (кроме полностью отключенных), которые вы хотите для сравнения, код также должен компилировать и давать правильные результаты, по крайней мере, на VС++ 2010 и g++.
Обсуждение в режиме ожидания
Помимо улучшенных алгоритмов, я также хотел бы получить некоторые тесты на нескольких разных платформах и компиляторах (позвольте использовать пропускную способность MB/s в качестве нашей стандартной единицы измерения). Я считаю, что код для моего алгоритма (я знаю, что тест sprintf
принимает некоторые ярлыки - теперь исправлен) - это четко определенное поведение по стандарту, по крайней мере, по предположению ASCII, но если вы видите поведение undefined или входы, для которых выход недействителен, укажите это.
Выводы:
Различные алгоритмы выполняются для g++ и VC2010, вероятно, из-за разных реализаций std::string
для каждого. VC2010 явно улучшает работу с NRVO, избавляясь от возвращаемого значения, помогая только на gcc.
Был найден код, который превосходит sprintf
на порядок. ostringstream
отстает в 50 и более раз.
Победителем вызова является user434507, который производит код, который работает на 350% от моей собственной скорости на gcc. Другие записи закрыты из-за прихотей сообщества SO.
Текущие (финальные?) чемпионы скорости:
- Для gcc: user434507, в 8 раз быстрее, чем
sprintf
: http://ideone.com/0uhhX - Для Visual С++: Timo, в 15 раз быстрее, чем
sprintf
: http://ideone.com/VpKO3