Let's say we've got the following piece of code and we've decided to optimise it a bit:
/// BM_NormalString
bool value = false;
std::string str;
str = "orthogonal";
if (str == "orthogonal") {
value = true;
}
So far we've come up with two pretty simple and straightforward strategies:
/// BM_charString
bool value = false;
char *str = new char[11];
std::strcpy(str, "orthogonal");
if (std::strcmp(str, "orthogonal") == 0) {
value = true;
}
delete[] str;
/// BM_charStringMalloc
bool value = false;
char *str = (char *) std::malloc(11);
std::strcpy(str, "orthogonal");
if (std::strcmp(str, "orthogonal") == 0) {
value = true;
}
free(str);
If we try and benchmark our three approaches we, quite surprisingly, won't see much of a difference. Although bench-marking it locally gives me even more surprisingly disconcerting results:
| Benchmark | Time | CPU | Iterations |
|----------------------|------------------|-----------|---------------|
| BM_charString | 52.1 ns | 51.6 ns | 11200000 |
| BM_charStringMalloc | 47.4 ns | 47.5 ns | 15448276 |
| **BM_NormalString** | 17.1 ns | 16.9 ns | 40727273 |
Would you say then, that for such rather small strings there's almost no point in going 'bare metal' style (by using C-style string functions)?
CodePudding user response:
For small strings, there's no point using dynamic storage. The allocation itself is slower than the comparison. Standard library implementers know this and have optimised std::basic_string
to not use dynamic storage with small strings.
Using C-strings is not an "optimisation".