Friday, August 15, 2008 10:44 AM
zekel
Watch out for sprintf()!
I was looking at some code the other day that does string concatenation with StringCchPrintf(ā%s%sā). I can imagine how this would have near optimal performance, and a hopeful developer could easily assume that in fact it has been tuned for this kind of concatenation. But measuring tells all. Three trivial implementations of concat using strsafe.h:
void concat_printf(PCWSTR str1, PCWSTR str2, PWSTR out, size_t max)
{
StringCchPrintfW(out, max, L"%s%s", str1, str2);
}
void concat_copy(PCWSTR str1, PCWSTR str2, PWSTR out, size_t max)
{
StringCchCopyEx(out, max, str1, &out, &max, 0);
StringCchCopy(out, max, str2);
}
void concat_cat(PCWSTR str1, PCWSTR str2, PWSTR out, size_t max)
{
StringCchCopy(out, max, str1);
StringCchCat(out, max, str2);
}
Measurements for short concatenating strings (~10 chars) and long strings (~1000 chars).
| method |
short |
long |
| concat_printf |
187 |
10530 |
| concat_copy |
15 |
952 |
| concat_cat |
15 |
1264 |
Unsurprisingly concat_copy() is the most efficient, with concat_cat() overhead of a strlen() only noticeable with longer strings. But wow, concat_printf() is shocking order of magnitude slower than either of the others. Taking a peak under the covers explains why: MSVCRT is using a FILE* stream abstraction that does a lot more work for every character copy. This is so the code for printf(), fprintf() and sprintf() can all be shared. Generalization at the cost of performance!