Не знаю, правда ли это, но когда я читал FAQ по одному из проблемных сайтов, я нашел кое-что, что привлекло мое внимание:
Проверьте свои методы ввода / вывода. В C ++ использование cin и cout слишком медленное. Используйте их, и вы гарантированно не сможете решить любую проблему с приличным объемом ввода или вывода. Вместо этого используйте printf и scanf.
Может кто-нибудь прояснить это? Действительно ли использование scanf () в программах на C ++ быстрее, чем использование cin >> something ? Если да, то стоит ли использовать его в программах на C ++? Я думал, что это специфично для C, хотя я только изучаю C ++ ...
c++
c
performance
io
zeroDivisible
источник
источник
Ответы:
Вот быстрый тест простого случая: программа для чтения списка чисел из стандартного ввода и XOR для всех чисел.
версия iostream:
версия scanf:
Полученные результаты
Используя третью программу, я создал текстовый файл, содержащий 33 280 276 случайных чисел. Сроки исполнения:
Изменение настроек оптимизации компилятора, похоже, не сильно повлияло на результаты.
Итак: разница в скорости действительно есть.
РЕДАКТИРОВАТЬ: Пользователь clyfish указывает ниже, что разница в скорости в значительной степени связана с функциями ввода-вывода iostream, поддерживающими синхронизацию с функциями CI / O. Мы можем отключить это с помощью вызова
std::ios::sync_with_stdio(false);
:Новые результаты:
C ++ iostream побеждает! Оказывается, именно эта внутренняя синхронизация / очистка обычно замедляет ввод-вывод iostream. Если мы не смешиваем stdio и iostream, мы можем отключить его, и тогда iostream будет самым быстрым.
Код: https://gist.github.com/3845568
источник
iostream
проигрывает, когда вы анализируете более одного целого числа за одинscanf
вызов.http://www.quora.com/Is-cin-cout-slower-than-scanf-printf/answer/Aditya-Vishwakarma
Производительность
cin
/cout
может быть медленной, потому что им нужно синхронизировать себя с базовой библиотекой C. Это важно, если будут использоваться как C IO, так и C ++ IO.Однако, если вы собираетесь использовать только ввод-вывод C ++, просто используйте строку ниже перед любыми операциями ввода-вывода.
Дополнительные сведения об этом см. В соответствующей документации libstdc ++ .
источник
Вероятно, scanf работает несколько быстрее, чем потоки. Хотя потоки обеспечивают большую безопасность типов и не должны анализировать строки формата во время выполнения, обычно они имеют преимущество в том, что они не требуют чрезмерного выделения памяти (это зависит от вашего компилятора и времени выполнения). Тем не менее, если производительность не является вашей единственной конечной целью и вы находитесь на критическом пути, вам действительно следует отдавать предпочтение более безопасным (более медленным) методам.
Здесь есть очень восхитительная статья, написанная Хербом Саттером « Строковые форматтеры усадебной фермы », в которой подробно рассказывается о производительности струнных форматеров, таких как
sscanf
и,lexical_cast
и о том, какие вещи заставляли их работать медленно или быстро. Возможно, это аналогично тому, что может повлиять на производительность между вводом-выводом стиля C и стилем C ++. Основное различие с форматерами, как правило, заключалось в безопасности типов и количестве выделений памяти.источник
Я только что провел вечер, работая над проблемой на UVa Online (Factovisors, очень интересная проблема, проверьте):
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=35&page=show_problem&problem=1080
Я получал TLE (превышен лимит времени) на свои заявки. На этих сайтах онлайн-судей по решению проблем у вас есть ограничение по времени в 2-3 секунды для обработки потенциально тысяч тестовых примеров, используемых для оценки вашего решения. Для таких ресурсоемких задач, как эта, на счету каждая микросекунда.
Я использовал предложенный алгоритм (читайте в дискуссионных форумах сайта), но все еще получал TLE.
Я изменил только «cin >> n >> m» на «scanf («% d% d », & n, & m)» и несколько крошечных «couts» на «printfs», и мой TLE превратился в «Принято»!
Так что да, это может иметь большое значение, особенно когда сроки ограничены.
источник
Если вам важны как производительность, так и форматирование строк, обратите внимание на FastFormat Мэтью Уилсона. библиотеку .
edit - ссылка на публикацию accu в этой библиотеке: http://accu.org/index.php/journals/1539
источник
Существуют реализации stdio ( libio ), которые реализуют FILE * как streambuf C ++ и fprintf как синтаксический анализатор формата времени выполнения. Потоки ввода-вывода не нуждаются в синтаксическом анализе формата времени выполнения, все это делается во время компиляции. Итак, с общими бэкэндами разумно ожидать, что iostreams будет быстрее во время выполнения.
источник
Да, iostream медленнее, чем cstdio.
Да, вам, вероятно, не следует использовать cstdio, если вы разрабатываете на C ++.
Сказав это, есть даже более быстрые способы получить ввод-вывод, чем scanf, если вас не волнует форматирование, безопасность типов, бла, бла, бла ...
Например, это настраиваемая процедура для получения числа из STDIN:
источник
Заявления
cin
иcout
в общем использовании , кажется, медленнее , чемscanf
иprintf
в C ++, но на самом деле они являются БЫСТРЕЕ!Дело в том, что в C ++ всякий раз, когда вы используете
cin
иcout
, по умолчанию выполняется процесс синхронизации, который гарантирует, что если вы используете обаscanf
иcin
в своей программе, то они оба будут синхронизироваться друг с другом. Этот процесс синхронизации требует времени. Следовательноcin
иcout
ПОКАЗАТЬСЯ медленнее.Однако, если для процесса синхронизации установлено значение «Не происходит»,
cin
выполняется быстрее, чемscanf
.Чтобы пропустить процесс синхронизации, включите в свою программу следующий фрагмент кода прямо в начале
main()
:Посетите этот сайт для получения дополнительной информации.
источник
Проблема в том, что
cin
это связано с большими накладными расходами, потому что это дает вам уровень абстракции надscanf()
вызовами. Вы не должны использоватьscanf()
over,cin
если пишете программное обеспечение на C ++, потому что это нужноcin
для. Если вам нужна производительность, вы, вероятно, все равно не будете писать ввод-вывод на C ++.источник
cin
"абстрактнее" (во время выполнения) чемscanf
? Я так не думаю ...scanf
должен интерпретировать строку формата во время выполнения, тогда как онiostream
знает формат во время компиляции.std::istream
настроен во время выполнения (с помощью манипуляторов ввода-вывода или путем установки флагов на самомistream
объекте). СFILE*
другой стороны, объект не имеет такого состояния, поэтому вызовscanf
в этом отношении намного более устойчив.В конце файла есть ошибка, но этот код C значительно быстрее, чем более быстрая версия C ++.
Исходный C ++ занял 30 секунд, код C занял 2 секунды.
источник
Конечно, смешно использовать cstdio вместо iostream. По крайней мере, когда вы разрабатываете программное обеспечение (если вы уже используете c ++ вместо c, то пройдите весь путь и используйте его преимущества вместо того, чтобы страдать от его недостатков).
Но, по мнению онлайн-судьи, вы не разрабатываете программное обеспечение, вы создаете программу, которая должна уметь делать то, что ПО Microsoft выполняет за 60 секунд за 3 секунды !!!
Итак, в этом случае золотое правило выглядит так (конечно, если у вас не возникнет еще больше проблем с использованием java)
источник
Даже если бы они
scanf
были быстрееcin
, это не имело бы значения. В большинстве случаев вы будете читать с жесткого диска или клавиатуры. Получение исходных данных в приложение занимает порядки больше времени , чем требуется ,scanf
илиcin
обрабатывать его.источник
iostream
он медленнее чем hdd. Да, это отстой.