views:

1253

answers:

8

Hello,

I don't know if this is true, but when I was reading FAQ on one of the problem providing sites, I found something, that poke my attention:

Check your input/output methods. In C++, using cin and cout is too slow. Use these, and you will guarantee not being able to solve any problem with a decent amount of input or output. Use printf and scanf instead.

Can someone please clarify this? Is really using scanf() in C++ programs faster than using cin >> something ? If yes, that is it a good practice to use it in C++ programs? I thought that it was C specific, though I am just learning C++...

+2  A: 

Even if scanf were faster than cin, it wouldn't matter. The vast majority of the time, you will be reading from the hard drive or the keyboard. Getting the raw data into your application takes orders of magnitude more time than it takes scanf or cin to process it.

Jay Conrod
What about IPC through pipes? Do you think there might be a noticeable performance hit there?
dreamlax
Even with IPC through pipes, much more time is spent going in and out of the kernel than just parsing it with scanf/cin.
Jay Conrod
Johannes Schaub - litb
+11  A: 

Probably scanf is somewhat faster than using streams. Although streams provide a lot of type safety, and do not have to parse format strings at runtime, it usually has an advantage of not requiring excessive memory allocations (this depends on your compiler and runtime). That said, unless performance is your only end goal and you are in the critical path then you should really favour the safer (slower) methods.

There is a very delicious article written here by Herb Sutter "The String Formatters of Manor Farm" who goes into a lot of detail of the performance of string formatters like sscanf and lexical_cast and what kind of things were making them run slowly or quickly. This is kind of analogous, probably to the kind of things that would affect performance between C style IO and C++ style. The main difference with the formatters tended to be the type safety and the number of memory allocations.

1800 INFORMATION
+1 thanks for that reference - i was trying to remember where i had read a formal comparison of the techniques, until i saw your reference :)
Faisal Vali
+9  A: 

Wow, talk about premature optimization. If not a ridiculous optimization. I/O is going to bottleneck your program well before cin >> x maxes out your quadcore CPU.

OK, snideness aside: No, it is not good practice to swap out <iostream> for <cstdio>. When in C++, use the C++ libraries. Do not use scanf, do not call malloc, do not pass go, do not collect $200.

John Kugelman
Please give me the C function for collecting $200, I could really use that right now.
dreamlax
if (!computer_is_on()) collect_200();
1800 INFORMATION
bool $200 = true;
Johannes Schaub - litb
@John: the site he is talking about is a competitive programming site. The **goal** is micro-optimization.
Evan Teran
Why can't we use C functions in C++? Isn't that the whole point of interoperability with the language? `scanf` and `printf` avoid memory allocations and expensive object construction, which may be critical for high-performance C++ applications.
Tom
+1  A: 

The problem is that cin has a lot of overhead involved because it gives you an abstraction layer above scanf() calls. You shouldn't use scanf() over cin if you are writing C++ software because that is want cin is for. If you want performance, you probably wouldn't be writing I/O in C++ anyway.

dreamlax
A: 

There are stdio implementations (libio) which implements FILE* as a C++ streambuf, and fprintf as a runtime format parser. IOstreams don't need runtime format parsing, that's all done at compile time. So, with the backends shared, it's reasonable to expect that iostreams is faster at runtime.

MSalters
I don't think so. I think GNU's libc is pure C and assembly.
Chris Lutz
You're right. It's libio I was thinking of.
MSalters
+2  A: 

If you care about both performance and string formatting, do take a look at Matthew Wilson's FastFormat library.

xtofl
Agree completely. But you need to be aware that FastFormat is only for output. It has no input/read facilities. (Not yet, anyway)
dcw
+2  A: 

I just spent an evening working on a problem on UVa Online (Factovisors, a very interesting problem, check it out):

http://uva.onlinejudge.org/index.php?option=com%5Fonlinejudge&amp;Itemid=8&amp;category=35&amp;page=show%5Fproblem&amp;problem=1080

I was getting TLE (time limit exceeded) on my submissions. On these problem solving online judge sites, you have about a 2-3 second time limit to handle potentially thousands of test cases used to evaluate your solution. For computationally intensive problems like this one, every microsecond counts.

I was using the suggested algorithm (read about in the discussion forums for the site), but was still getting TLEs.

I changed just "cin >> n >> m" to "scanf( "%d %d", &n, &m )" and the few tiny "couts" to "printfs", and my TLE turned into "Accepted"!

So, yes, it can make a big difference, especially when time limits are short.

Bogatyr
+1  A: 

Of course it's ridiculous to use cstdio over iostream. At least when you develop software (if you are already using c++ over c, then go all the way and use it's benefits instead of only suffering from it's disadvantages).

But in the online judge you are not developing software, you are creating a program that should be able to do things Microsoft software takes 60 seconds to achieve in 3 seconds!!!

So, in this case, the golden rule goes like (of course if you dont get into even more trouble by using java)

  • Use c++ and use all of it's power (and heaviness/slowness) to solve the problem
  • If you get time limited, then change the cins and couts for printfs and scanfs (if you get screwed up by using the class string, print like this: printf(%s,mystr.c_str());
  • If you still get time limited, then try to make some obvious optimizations (like avoiding too many embedded for/while/dowhiles or recursive functions). Also make sure to pass by reference objects that are too big...
  • If you still get time limited, then try changing std::vectors and sets for c-arrays.
  • If you still get time limited, then go on to the next problem...
Carlos Pacheco