Потоки ввода-вывода, которые рискуют быть отвергнутыми, в целом медленнее и громоздче, чем их аналоги C. Это не причина избегать их использования во многих целях, поскольку они более безопасны (когда-нибудь сталкивались с ошибкой scanf или printf? Не очень приятно) и более общие (например, перегруженный оператор вставки, позволяющий выводить пользовательские типы). Но я бы также сказал, что это не причина использовать их догматически в очень критичном по производительности коде.
Хотя я нахожу результаты немного удивительными. Из трех перечисленных вами, я бы подозревал, что это будет самым быстрым:
char command[5];
cin.ignore();
cin.read(command, 5);
Причина: не требуется выделение памяти и простое чтение символьного буфера. Это также верно для вашего примера C ниже, но вызов scanf для многократного чтения одного символа не является оптимальным даже на концептуальном уровне, поскольку scanf должен каждый раз анализировать строку формата, которую вы передали. Мне были бы интересны подробности вашего кода ввода-вывода, поскольку кажется, что существует разумная вероятность того, что что-то не так произойдет, когда вызовы scanf для чтения одного символа оказываются самыми быстрыми. Я просто должен спросить и не хотел обидеть, а действительно ли код скомпилирован и связан с включенными оптимизациями?
Теперь что касается вашего первого примера:
std::string command;
std::cin >> command;
Мы можем ожидать, что это будет немного медленнее, чем оптимально, по той причине, что вы работаете с контейнером переменного размера (std::string), который должен будет задействовать некоторые выделения кучи для чтения в желаемом буфере. Когда дело доходит до проблем стека и кучи, стек всегда значительно быстрее, поэтому, если вы можете предвидеть максимальный размер буфера, необходимый в конкретном случае, простой символьный буфер в стеке будет лучше, чем std::string для ввода (даже если вы использовали резерв). Это также верно для массива в стеке, в отличие от std::vector, но эти контейнеры лучше всего использовать в случаях, когда вы не можете заранее предсказать размер. Где std::string может быть быстрее, так это в тех случаях, когда у людей может возникнуть соблазн многократно вызывать strlen, где лучше хранить и поддерживать переменную размера.
Что касается деталей gprof, то он должен освещать эти проблемы. Вы смотрите на полный график вызовов, а не на плоский профиль? Естественно, в этом случае плоский профиль может ввести в заблуждение. Мне нужно знать некоторые дополнительные подробности о том, как вы используете gprof, чтобы дать лучший ответ.
person
stinky472
schedule
01.02.2012