При риске понижения, потоки ввода / вывода, как правило, медленнее и объемнее, чем их аналоги на языке Си. Это не причина избегать их использования, хотя во многих целях они более безопасны (когда-либо сталкивались с ошибкой 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, чтобы дать лучший ответ.