-
November 29th, 2004, 06:51 PM
#1
CString -vs- std:string ?
A couple of questions re CString -vs- std::string ...
1. What are the pros and cons of using CString -vs- std::string ?
2. If you were going to pick one to be your primary string type til the end of time, which would you pick?
Thanks
-
November 29th, 2004, 07:03 PM
#2
Re: CString -vs- std:string ?
std::string is part of the C++ Standard so, IMO, that is the best choice
-
November 29th, 2004, 07:26 PM
#3
Re: CString -vs- std:string ?
And please do a search.. There have been oodles of threads about this in the past.
Insert entertaining phrase here
-
November 30th, 2004, 05:28 AM
#4
Re: CString -vs- std:string ?
Originally Posted by rlewkov
A couple of questions re CString -vs- std::string ...
1. What are the pros and cons of using CString -vs- std::string ?
2. If you were going to pick one to be your primary string type til the end of time, which would you pick?
Thanks
Never take something with you for ever. New things often appear and you should always use what is the best. There are pro and cons for the string but just do a research on the forum. As for myself, when I am doing a MFC project a use CString.
-
November 30th, 2004, 12:28 PM
#5
Re: CString -vs- std:string ?
If you're using MFC, CString is a far better choice over std::string.
IMHO, CString is the only MFC class that is better then the STL version.
The std::string that comes with VC++ 6.0/7.x is very inefficient compare to CString.
std::string peforms very badly compare to CString.
Also IMHO, CString has a better string interface then std::string does.
CString is also easier to code when you want to be able to compile a project to either UNICODE or ANSI.
CString has an operator LPCTSTR(), so you don't have to explicitly cast.
With std::string, you have to use the c_str() member function to pass the pointer.
This point can also be consider a CON, but IMHO, the benifit far aways the down side.
CString has a GetBuffer() function which allows you to modify the buffer directly.
According to the C++ standard there's no portable way to modify the std::string buffer directly.
CString has a CompareNoCase function so you can make case insensitive comparisons.
CString works easier with many MFC and Windows API functions.
The major CON with CString is that is not portable. However, there are some CString versions on the net that are portable.
-
November 30th, 2004, 03:44 PM
#6
Re: CString -vs- std:string ?
Originally Posted by Axter
CString has a GetBuffer() function which allows you to modify the buffer directly. According to the C++ standard there's no portable way to modify the std::string buffer directly.
Well...I do not want to get into all of the above since our view is very different from each other in this case, however....the above is not really true...there is of course a portable way...using a 'vector' as a temporary buffer...
-
November 30th, 2004, 03:50 PM
#7
Re: CString -vs- std:string ?
Originally Posted by Andreas Masur
Well...I do not want to get into all of the above since our view is very different from each other in this case, however....the above is not really true...there is of course a portable way...using a 'vector' as a temporary buffer...
My comment is true.
Even if you use vector as a temporary buffer, you're still not modifying the buffer directly.
There are many ways to modify the std::string buffer indirectly. But my comment reffers to direct modification.
-
November 30th, 2004, 04:23 PM
#8
Re: CString -vs- std:string ?
Originally Posted by Axter
The std::string that comes with VC++ 6.0/7.x is very inefficient compare to CString.
std::string peforms very badly compare to CString.
You have to show this to us in terms of real code. Badly doing what operations?
CString works easier with many MFC and Windows API functions.
Maybe MFC functions that require a CString, but I don't see how a Windows API function would be easier with CString as opposed to std::string.
The major CON with CString is that is not portable. However, there are some CString versions on the net that are portable.
And many of those versions actually wrap std::string with calls that mimic CString.
Also IMHO, CString has a better string interface then std::string does
The one disadvantage to CString that has not been pointed out is that std::string handles binary data easily with no tricks. I don't know if CString can handle binary data (for example, appending binary data on a CString that may contain embedded NULLs). In that respect, std::string has the functions to handle binary data (i.e, append(), data(), assign(), etc.), that AFAIK do not exist in CString.
Regards,
Paul McKenzie
-
November 30th, 2004, 04:58 PM
#9
Re: CString -vs- std:string ?
Originally Posted by Paul McKenzie
You have to show this to us in terms of real code. Badly doing what operations?
If you run the code below, you'll see the peformance difference between CString and std::string.
Run the test in release mode (not debug).
The code below will show that CString out peformance std::string by a factor of MORE then 10 to 1.
Compile in VC++ 6.0 using std::string that comes with VC++.
Code:
int dummy_var = 0;
void function1(const char*Data)
{
CString strData = Data;
dummy_var += strData[99];
}
void function2(const char*Data)
{
std::string strData = Data;
dummy_var += strData[99];
}
void function3(const char*Data)
{
CString strData;
strData = Data;
dummy_var += strData[99];
}
void function4(const char*Data)
{
std::string strData(513, 0);
strData = Data;
dummy_var += strData[99];
}
void function5(const char*Data)
{
std::string strData(999, 0);
strData = Data;
dummy_var += strData[99];
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
const QtyTimesTest = 99999;
DWORD StartTime, LenTime1=0, LenTime2=0, LenTime3=0, LenTime4=0, LenTime5=0;
const int SizeData = 512;
char DummyData[SizeData+1];
memset(DummyData, 'x', SizeData);
DummyData[SizeData] = 0;
{
StartTime = GetTickCount();
for (int i = 0;i < QtyTimesTest;++i)
{
function1(DummyData);
}
LenTime1 += (GetTickCount() - StartTime);
}
{
StartTime = GetTickCount();
for (int i = 0;i < QtyTimesTest;++i)
{
function2(DummyData);
}
LenTime2 += (GetTickCount() - StartTime);
}
{
StartTime = GetTickCount();
for (int i = 0;i < QtyTimesTest;++i)
{
function3(DummyData);
}
LenTime3 += (GetTickCount() - StartTime);
}
{
StartTime = GetTickCount();
for (int i = 0;i < QtyTimesTest;++i)
{
function4(DummyData);
}
LenTime4 += (GetTickCount() - StartTime);
}
{
StartTime = GetTickCount();
for (int i = 0;i < QtyTimesTest;++i)
{
function5(DummyData);
}
LenTime5 += (GetTickCount() - StartTime);
}
printf("Time duration is as follow:\n\
LenTime1 = %li\n\
LenTime2 = %li\n\
LenTime3 = %li\n\
LenTime4 = %li\n\
LenTime5 = %li\n",
LenTime1, LenTime2, LenTime3, LenTime4, LenTime5);
if (!dummy_var) printf("dummy %i", dummy_var);
system("pause");
Originally Posted by Paul McKenzie
Maybe MFC functions that require a CString, but I don't see how a Windows API function would be easier with CString as opposed to std::string.
Example:
int MessageBox(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);
Code:
CString CstrData = _T("Hello");
std::string stdStrData = "Hello";
MessageBox(NULL, CstrData, NULL, 0); //Compiles on UNICODE and ANSI
MessageBox(NULL, stdStrData.c_str(), NULL, 0); //Only compiles on ANSI (need wstring for UNICODE)
The CString variable is handed over to the API function directly, without having to call a member function. Moreover, it compiles on UNICODE and ANSI projects without having to modify the code, or create another compiler directive.
Originally Posted by Paul McKenzie
And many of those versions actually wrap std::string with calls that mimic CString.
I agree.
Originally Posted by Paul McKenzie
The one disadvantage to CString that has not been pointed out is that std::string handles binary data easily with no tricks. I don't know if CString can handle binary data (for example, appending binary data on a CString that may contain embedded NULLs). In that respect, std::string has the functions to handle binary data (i.e, append(), data(), assign(), etc.), that AFAIK do not exist in CString.
CString can also handle binary data.
Example code:
Code:
char data1[] = "\0\1\2\3\4\5\6\7 Hello World";
char data2[] = "\0\7\6\5\4\3\2\1";
CString binData(data1, sizeof(data1)-1);
binData += CString(data2, sizeof(data2)-1);
for (int i = 0;i < binData.GetLength();++i)
{
cout << (int)binData[i] << endl;
}
system("pause");
More over, the GetBuffer() function can be used similar to the data() function of std::string.
I agree that not having an assign() nor an append() function is a limitation on the CString class. And I'm surprise MS didn't include these functions.
However, you can do an append by using the += operator as in my above example. And an assign can be done by either iterating through each position via SetAt, or modifying the buffer directly via GetBuffer() function.
A lot of critics of CString, don't fully understand the class, and don't realize the average peformance value.
Last edited by Axter; November 30th, 2004 at 05:24 PM.
-
November 30th, 2004, 06:20 PM
#10
Re: CString -vs- std:string ?
f you run the code below, you'll see the peformance difference between CString and std::string.
Run the test in release mode (not debug).
The code below will show that CString out peformance std::string by a factor of MORE then 10 to 1.
Compile in VC++ 6.0 using std::string that comes with VC++.
Do a reserve() on the string before using it. Then you should see hardly any difference.
Almost all of the standard container classes, including std::string, has a reserve() method that addresses the issue that you demonstrated in your code. The ones that don't are the associative types (maps).
In general, what usually ends up in real code is a series of many concatenations on one string. Why not run a benchmark on that, since that is what is more likely to be done in a real application.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; November 30th, 2004 at 06:34 PM.
-
November 30th, 2004, 06:23 PM
#11
Re: CString -vs- std:string ?
You're not being fair to std::string with your ANSI vs UNICODE example. Add this to your project:
Code:
#ifdef _UNICODE
typedef tstring std::wstring;
#else
typedef tstring std::string;
#endif
and we're on a more equal footing, since that's what happens with CString, anyway. Then the only difference is between the two is that you have to call the c_str() function on the tstring. To my mind that is a distinct advantage that string has over CString. Take the implicit conversion out of CString and it will be a much better class. I also don't like the GetBuffer() function of CString - it opens it up to all sorts of potential problems.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
November 30th, 2004, 06:30 PM
#12
Re: CString -vs- std:string ?
Also, I ran your code. There is hardly any difference in the times, even without reserve():
Time duration is as follow:
LenTime1 = 109
LenTime2 = 141
LenTime3 = 93
LenTime4 = 188
LenTime5 = 203
Running VC 6.0, Pentium 4, 3.00 GHZ
Regards,
Paul McKenzie
-
November 30th, 2004, 06:31 PM
#13
Re: CString -vs- std:string ?
Originally Posted by Graham
You're not being fair to std::string with your ANSI vs UNICODE example. Add this to your project:
Code:
#ifdef _UNICODE
typedef tstring std::wstring;
#else
typedef tstring std::string;
#endif
and we're on a more equal footing, since that's what happens with CString, anyway. Then the only difference is between the two is that you have to call the c_str() function on the tstring. To my mind that is a distinct advantage that string has over CString. Take the implicit conversion out of CString and it will be a much better class. I also don't like the GetBuffer() function of CString - it opens it up to all sorts of potential problems.
That is not exactly what happens with CString. The CString type char itself is change instead of the entire object.
IMHO, the advantages of implicit conversion out ways the disadvantages.
I guess we'll have to agree to disagree.
-
November 30th, 2004, 06:32 PM
#14
Re: CString -vs- std:string ?
Originally Posted by Paul McKenzie
Also, I ran your code. There is hardly any difference in the times, even without reserve():
Running VC 6.0, Pentium 4, 3.00 GHZ
Regards,
Paul McKenzie
Did you run it in release or debug mode?
Those results look like debug results, and not release.
FYI:
Even in your results, the std::string is about 40% slower the CString.
That's a big difference to me.
And using reserve is not a valid argument for this test. You don't always know the size that you're going to need for your buffer in advance.
Last edited by Axter; November 30th, 2004 at 06:36 PM.
-
November 30th, 2004, 06:36 PM
#15
Re: CString -vs- std:string ?
Release mode (maximize speed).
For debug, I get these numbers:
Time duration is as follow:
LenTime1 = 234
LenTime2 = 203
LenTime3 = 344
LenTime4 = 422
LenTime5 = 437
Regards,
Paul McKenzie
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|