3

I am printing information about a struct which only contains information which will all be a single digit (small indices and char which act as bools mostly).

I want my printf calls to be as efficient as possible. So would it be better to use the normal %i/%d format specifiers, or is it better to use %c and add 0x30 ('0') to the number, since then there shouldn't need to be any formatting for printf to do?

Edit/Clarification: I have profiled some small programs which try both techniques, and the %c can be faster. If this were for production code, I would just stick to the %d, but this is specifically for speed-based competitions. (sorry because that wasn't clear before).

Edward Minnix
  • 2,889
  • 1
  • 13
  • 26
  • 1
    Use whatever is more clear (`%d`). I doubt your program's performance is dictated by printing a number. – Federico klez Culloca Feb 28 '19 at 19:53
  • did you measure any impact? this kind of optimization seem really useless if you can't measure anything. – OznOg Feb 28 '19 at 19:53
  • 1
    Use `%d` — it explains what your doing and won’t be measurably slower. – Jonathan Leffler Feb 28 '19 at 19:53
  • Try and profile. If you can't see the difference (what I would bet on), then I guess you know the answer. Using `printf` where the performance is *that* critical is not making sense by itself. – Eugene Sh. Feb 28 '19 at 19:54
  • 2
    If this is a concern, don't use `printf` at all, just write directly to the file buffer with `fwrite` so you have full control over performance. Or even better, call a system-dependant function like POSIX `write`. – yyny Feb 28 '19 at 20:09
  • If you can measure the difference, you have your answer. But I doubt you'll be able to measure any difference. – Steve Summit Feb 28 '19 at 20:22
  • `'0'+ch` and `%c` is off cause better option, if you sure it is only one digit. printf will format integer to string using mod `%` and idiv `/` operations Both of them expensive. For example intel takes 4 CPU ticks for both, as well as formatting i.e. itoa have a loop for checking when value becomes 0, each loop iteration is additional CPU fee for cmp and jnz instructions. itoa also may revert the formatted string at the end, depending on implementation. However, compilers like gcc able to intrinsic printf so profiling may show no difference – Victor Gubin Feb 28 '19 at 20:45
  • If `%c` is measurably faster and you care that much, you should probably use `putchar` (or [`putchar_unlocked`](http://man7.org/linux/man-pages/man3/unlocked_stdio.3.html)) instead of interpreting a format string. – rici Feb 28 '19 at 22:33

2 Answers2

3

The only way to know for sure is to code up both versions and profile them (or compare the generated machine code). Having said that, I doubt you'd see much difference in runtime performance. Modern compilers are smart, and standard library implementations are tuned to be as efficient as possible. It's quite likely that your printf implementation already has special case handling for single-digit integers that does something similar to what you are proposing. And all of that's down in the noise compared to the overhead of just calling printf in the first place.

Code should be, in order of importance:

  1. Correct - it does everything it is supposed to do, and nothing it isn't supposed to do;
  2. Robust - it shouldn't fall over and die if somebody looks at it funny;
  3. Secure - it's not a malware vector, it doesn't expose any data it shouldn't;
  4. Maintainable - some poor schmuck is eventually going to have to change this code to add functionality (or fix a defect);
  5. Efficient - it shouldn't take any more space or time than necessary to accomplish a given task, which is often driven by choice of algorithm and data structures more than anything specific micro-optimization.

I'd argue that your approach makes your code less maintainable, because it's a non-obvious way to achieve a given result.

John Bode
  • 119,563
  • 19
  • 122
  • 198
1

Since you are printing integer numbers, use %d, which improves readability.

Using the one over the other won't affect performance in any significant way.

If your application's bottleneck is really the printing phase, then considering using another approach than printf(). Some ideas: use fwrite(), optimize stdout, or POSIX write(), as @YoYoYonnY suggested.

In general, printing in stdout is relatively slow, in comparison to doing computations, for example...

HyperTip: Premature optimization is the root of evil - D. Knuth.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • Thanks for your input. For production code, I would definitely use `%d`. I'm trying to optimize the heck out of an output loop because it's part of a speed-based competition. But I'll try other printing methods as well. – Edward Minnix Feb 28 '19 at 20:05
  • You are welcome @EdwardMinnix, you asked a good question BTW, +1! Yes, try other functions as well.. Maybe you could share the code you profiled (you used optimization flags I assume) in [wandbox](https://wandbox.org/), so that we can try stuff in parallel! :) – gsamaras Feb 28 '19 at 20:07