Если вы пишите на С++, то регулярно бывает так, что ввод написанный через std::cin начинает тормозить из-за громоздких входных данных. Конечно правильнее в таких случаях сразу же писать чтение данных более эффективно - хотя бы с помощью функции scanf. Но если тестирующая система использует GNU C++ (проверял на MinGW 4.4.1, но думаю и на других версиях тоже будет работать), а переписывать программу не хочется, то можно катастрофически ускорить чтение всего одной строкой, размещенной в начале программы: ios_base::sync_with_stdio( 0) .
На моем примере, где надо было найти сумму миллиона целых чисел, это ускорило программу в 4.5 раза, приблизив время работы к варианту со scanf. Пробовал запускать этот же тест на MS Visual C++ 9.0 - но не ускоряет.
также виден прирост скорости операций I/O на GNU C++3.4.2
Я тоже пишу на Java. Как раз для таких случаев у меня припасён переписанный Сканер (Извините, если отступы сбились)
class Scanner{
StreamTokenizer in;
Scanner(InputStream stream){
in = new StreamTokenizer(new InputStreamReader(stream));
}
void asserT(boolean e){
if (!e){
throw new Error();
}
}
int nextInt(){
try{
in.nextToken();
asserT(in.ttype == in.TT_NUMBER);
asserT(in.nval == (int)in.nval);
return (int) in.nval;
}catch (Exception e) {
throw new Error();
}
}
}
Ну и метод запуска программы
void run(){
in = new Scanner(System.in);
out = new PrintWriter(System.out);
try {
solve();
}finally{
out.close();
}
}
Никаких посторонних "шаманств" не надо. Ассерты установлены, чтобы программа не дай бог не получила WA или ещё что-нить при некорректном вводе вместо Crash.
some one doesn't say anything twice unless he has a good reason for it ;)
Сейчас при решении кодчифа ( http://www.codechef.com/MARCH12/problems/HDELIVER ) столкнулся с одной проблемой.. раньше не встречал.. Кто-нибудь в курсе почему происходит такая вещь?
Значится так: я всегда пишу код в своём шаблоне, где у меня есть также строка ios::sync_with_stdio(0); в самом начале main(). Я обычно считываю cin/cout и программа не захотела заходить по ТЛ... ну естественно в первую очередь написал scanf(), но как бы зачем это делать в тех местах, которые отработают раз 100... так что исправил только там, где много данных считывается. Засылаю, получаю рантайм (ошибка доступа). Вобщем выяснил, что что-то не так считывается. Задача зашла только когда либо закомментил ios::sync_with_stdio(0); либо когда все cin исправил на scanf(). То есть проблема именно в том, что не может быть написано одновременно ios::sync_with_stdio(0); и чередование в середине программы cin и scanf(). Причём мне почему-то кажется, что раньше я так делал и никаких проблем связанных с этим не возникало.
Ну тут чётко написано: If the synchronization is turned off, the C++ standard streams are allowed to act independently. In this case using both C and C++ standard streams at the same time leads to undefined behavior.
О! Спасибо!
Кстати возможно, что до этого всё было норм, ибо я отправлял в MSVS (а в ней работает всё корректно), а тут gcc-4.3.2.
Мелкософт обычно плевать хотели на все стандарты, а тем более на какую-то там ios_base::sync_with_stdio — видно они не заморачиваются и синхронизируют любой i/o, игнорируя Ваши флаги.
Зачем так категорично :) Просто реализация от Microsoft зачастую в случае undefined behavior молча выбирает какой-нибудь из вариантов дальнейшего выполнения программы. Это вполне соответствует требованиям стандарта. Другое дело, что часто такое боком выходит.
Значение флага ios_base::sync_with_stdio — это не undefined behavior, это вполне осмысленное поведение, которое ожидает программист, выставив этот флаг. Но Microsoft этот флаг просто игнорируют (им лень было это реализовывать).
Я вел речь об одновременном использовании sync_with_stdio(false) и чередовании cin/scanf, когда говорил про UB. А о том, что в реализации от Dinkumware (это ведь, кстати, не Microsoft виноват :) ) этот флаг игнорируется, я не знал. Вот что написано у них на сайте: "In this implementation there is no need to call the iostream member function sync_with_stdio to ensure such synchronization, nor is there any performance benefit in disabling it". И дело тут, похоже, не в лени..
UB при чередовании cin/scanf — есть очевидное следствие отсутствия синхронизации, что в свою очередь дает прирост производительности. То, что в реализации, используемой Microsoft, не реализован такой режим — вовсе не есть плюс.
Я нигде и не говорил, что это плюс. Просто делать утверждения, что во всем виновата Microsoft, лень, etc, не подтверждая это фактами — легко. На деле же, обычно, причины каких-то "косяков" гораздо глубже.
Хм... то, что было предусмотрено проектировщиками языка, но не было реализовано — как это назвать? Если не лень, то чёткий экономический просчёт — зачем тратить деньги на какую-то там оптимизацию, если это и так можно продать?
Главное же как себя подать — можно вон гордо написать "In this implementation there is no need to call the iostream member function sync_with_stdio to ensure such synchronization", хотя слова "In this implementation" явно лишние — в стандарте чётко прописано поведение по-умолчанию.
Ну а оправдание типа "наш продукт такой гавёный не по нашей вине, а потому что мы покупаем для него такой-то кусок в другой фирме" звучит смешно. ;)
А есть бенчмарки, которые показывают сильно лучшую скорость у gcc при выключенном синке? Если это не так, то я бы назвал это плюсом библиотеки от MS
без синка — TL с синком — заходит за половину отведенного времени. Не редкость.
Я не говорю о разнице gcc с синком и без, я говорю о разнице gcc с выключенным синком и MSVS
Egor, пожалуйста:
1255624 — G++ c включенным синком (200 мс)
1255626 — G++ с выключенным синком (50 мс)
1255627 — MS C++ (230 мс)
Вам очень везло. :-) У меня как и ожидается из названия и описания метода даже следующая простая программа загибается на gcc 4.3 mingw:
А название функции ios::sync_with_stdio не намекает? :)
:-D Ну да... даже не вдумывался, в одно время тупо запомнил и всё :)
In my case , it is not working . See 4082110 , it has been accepted WITH OUT using "ios_base::sync_with_stdio(0)" , but when i used it in 4082115 , i got TLE .
What is wrong here ?
In my case , it is not working . See 4082110, it has been accepted WITH OUT using "ios_base::sync_with_stdio(0)" , but when i used it in 4082115 , i got TLE .
What is wrong here ?
Now your code WITH "ios_base::sync_with_studio(0)" gets Accepted 4083080.
What's the difference between these two code? I haven't find any change. :(
One of them has the line "ios_base::sync_with_studio(0)", but other doesn't.
when U use cin cout & scanf printf together the c++ itself syncs theme with each other it means that if U cout 1 then printf 2 then cout 3 then printf 4 it handles the problem of different buffers & you'll face this output:1 2 3 4 but if U place that code in the beginning of your code U'll surely face 1 before 3 & 2 before 4 but U can face 1 3 2 4 ,1 2 3 4, 2 4 1 3 ... but this disables a check which slows the code so U shouldn't use scanf & printf when this check is disabled but disabling the check isn't some times effective enough & you should use scanf printf to make a code quicker but if U want to make the code the quickest U can read the output by getchar() it's the quickest way but having it's own problems which isn't sometimes a good idea.anyway it's on your own decision to choose which one.
But sometimes using scanf is not the fastest when reading too large input size.
We can use getchar() to read integer byte by byte to make the input much faster and avoid TLE.