So how often do you change individual characters within a string? Don't you more often extract substrings, combine strings and search strings?
I still stand by this:
Quote: "the std::string class is 9 times out of 10 going to be faster than raw string access"
You can always find exceptions, but how often do they happen for real?
Now in actual fact, the combining of 2 strings into a third, I can code faster in C than in C++, but the result is 13 lines of code as opposed to the 3 equivalent lines in C++:
#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <Mmsystem.h>
#pragma comment(lib, "Winmm.lib")
#include <stdio.h>
#include <tchar.h>
#include <time.h>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
const char lit_a[] = "Hello World.";
const char lit_b[] = "How are things today?";
void DoChar()
{
// Construct the 2 source strings
char *a = strdup(lit_a);
char *b = strdup(lit_b);
// Construct a third by concatenating the 2 source strings together
int a_len = strlen(a);
int b_len = strlen(b);
char* c = (char*)malloc( a_len + 1 + b_len + 1 );
memcpy(c, a, a_len);
c[a_len] = ' ';
strcpy(c + a_len + 1, b);
// Destroy all 3 strings as they go out of scope
free(c);
free(b);
free(a);
}
void FastDoChar()
{
// Construct the 2 source strings
int a_len = strlen(lit_a);
char* a = (char*)malloc(a_len + 1);
memcpy(a, lit_a, a_len + 1);
int b_len = strlen(lit_a);
char* b = (char*)malloc(b_len + 1);
memcpy(b, lit_b, b_len + 1);
// Construct a third by concatenating the 2 source strings together
char* c = (char*)malloc( a_len + 1 + b_len + 1 );
memcpy(c, a, a_len);
c[a_len] = ' ';
memcpy(c + a_len + 1, b, b_len + 1);
// Destroy all 3 strings as they go out of scope
free(c);
free(b);
free(a);
}
void DoString()
{
// Construct the 2 source strings
string a = lit_a;
string b = lit_b;
// Construct a third by concatenating the 2 source strings together
string c = a + " " + b;
// Destroy all 3 strings as they go out of scope
}
int main(int argc, char* argv[])
{
const int Count = 100000;
{
DWORD Start = clock();
for (int i = 0; i < Count; ++i)
DoChar();
DWORD Finish = clock();
cout << "Char took " << Finish-Start << "msn";
}
{
DWORD Start = clock();
for (int i = 0; i < Count; ++i)
DoString();
DWORD Finish = clock();
cout << "String took " << Finish-Start << "msn";
}
{
DWORD Start = clock();
for (int i = 0; i < Count; ++i)
FastDoChar();
DWORD Finish = clock();
cout << "Fast Char took " << Finish-Start << "msn";
}
cin.get();
return 0;
}
As soon as I start passing things around though, the string class starts to win again ... purely because I'm constantly having to get the string length almost every time I use the string - that's why the 'fast' C version wins in the above code (by removing the implicit strlen within the strdup call), and it's the only reason.
Quote: "Surely if used as efficiently as possible C strings can't be slower than standard strings?"
Sure, but look at the code I had to use to do it! Awful stuff.
In my view, unless you have absolutely
proven that your string handling is the
true bottleneck to your code, you just don't want to go there.