Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm looking at optimizing some string formatting code that's hit a lot in our code. We had been using ostringstream, and I converted the code to use sprintf (actually Microsoft's more secure sprintf_s). I've traded type safety for run-time performance. But I've debugged enough sprintf related weird crashes to know that sprintf has its own serious flaws that the compile time checking of ostringstream catch. But ostringstream is more than an order-of-magnitude slower then sprintf by my measure, and that's not tolerable in this code. I'm also not thrilled with the readability of C++ stream string formatting, but this may be entirely subjective.

So unfortunately when formatting strings in C++ I've got several "standard" options that are suboptimal:

  1. sprintf -- fast, but not type safe. Can have insidious bugs when the wrong format string is not used.
  2. ostringstream -- slow, but type safe. IMO Ugly, too verbose, and difficult to read.
  3. boost::format -- a little more readable then ostringstream IMO, but in my performance benchmarks appears to be even slower then ostringstream, so this is out.

To summarize, I'm not really satisfied with the "standard" options. I'd like something that takes both performance and type safety seriously. What other string formatting options are out there for C++?

share|improve this question
    
What's the nature of your output? You might have to roll your own sprintf wrapper if you want type safety. –  Karl Bielefeldt Dec 21 '11 at 17:24
    
Couldn't you just search for sprintf in your code, and review every use carefully? –  David Thornley Dec 21 '11 at 17:40
    
Echoing @KarlBielefeldt - what is your specific use case? If logging - pantheios.org may help some. If something else - perhaps more details will lead to a better set of answers... –  sdg Dec 21 '11 at 17:44
1  
I haven't tried it personally, but take a look at SFIO (Safe, Fast I/O library for C). www2.research.att.com/~gsf/download –  Aidan Cully Dec 21 '11 at 17:48
1  
Writing it yourself can be the sensible choice in some cases. If you are only looking for basic string formatting, like int-to-ascii conversions, then it is easy to write a snippet that is approximately 100 times more effective than sprintf, both in terms of speed and memory consumption. The number 100 is based on one of my embedded projects, where I compare my own itoa() version with sprintf. Implementing your own itoa() could perhaps be worth the less than 30 minutes of your time it takes to write that function. Though of course that assumes C strings and it won't have much type safety. –  user29079 Dec 22 '11 at 12:37

5 Answers 5

This is not a complete answer however, i guess, given that performance matters - scaling up sprintf might be a better starting point.

One area where you need to look at is how GCC works. Basically, even though C (and C++) doesn't bother as a language to do typecheck of %d vs. having really integer on the respective arguments, typically GCC always catches that and gives Warnings. You can actually treat Warning as Error with -Werror options. The point is that essentially GCC already does 'type safety' verification at compile time. That is exactly what you need.

share|improve this answer
    
Yeah MSVC does this also, but it doesn't always catch everything. There's still some things that appear to get by. –  Doug T. Dec 21 '11 at 17:38

Streams are very slow because they have a relatively inefficient implementation, and also because they have a whole bunch of overhead bells and whistles that you really don't need. Fundamentally, they serve the exact purpose you need.

The question, ultimately, is about exactly how much effort you're willing to go to and how many types you're outputting. sprintf isn't just unsafe, it's also completely unextendable, something that isn't true of ostringstream. You can also use expression templates to improve it's performance. The performance problem of ostringstream is not endemic to it's design at all.

share|improve this answer

I didn't try it myself but have been looking for such a solution some time ago and often came to find FastFormat : http://www.fastformat.org/

I guess you could give it a try?

share|improve this answer
    
+1 because I want someone else to try this first. :-) –  sdg Dec 21 '11 at 21:36
    
FastFormat looks like a nice library. I was considering using it myself, but unfortunately it has limited formatting options and it is very large and has an even larger dependency (stlsoft libraries) so I couldn't justify its use for a relatively simple task of string formatting. That's why I wrote my own library which is only 1.3 kLOC. –  vitaut Dec 30 '12 at 5:13

I suspect you are looking for a silver bullet. It's really is a triangle, (fast, powerful, safe). You need fast, so your only choice is powerful or safe, you cannot have both. sprintf is fast and powerful, at the expense of safety.

You should be able to wrap sprintf in ways that restrict it's use (making it less powerful, more safe), and though run-time checks and rigorous code review, ensure your performance and safety targets are met. If this cannot be achieved, think carefully why not before choosing another option.

share|improve this answer

I recommend this formatting library which I wrote recently. Here is an incomplete list of its features:

  • Format string syntax similar to the one used by str.format in Python.
  • Type safety and support for user-defined types.
  • High speed: performance of the current implementation is close to that of glibc's (s)printf and better than performance of IOStreams. See Speed tests.

It's a new library, but it already supports almost all of the formatting options of printf (with different syntax), in addition to that it supports positional arguments, center alignment, custom fill character and user-defined types.

share|improve this answer
1  
Thanks! I actually commented on your blog a while back. Im looking forward to playing with your library. I've also got a lot of ideas based on my work around optimizing string formatting –  Doug T. Dec 30 '12 at 16:35
    
@DougT: Yes, I remember. I just thought that it might be useful for others who come across your question. –  vitaut Dec 30 '12 at 16:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.