calin radoni's humble web presence |
home![]() ![]() ![]() |
Speed considerations in using the CString class
One day I have written a class to load and process a somehow large (~400k) text file. The problem was the time required for the operation to complete, a little bit over 3 seconds. Unacceptable I said.
My first idea was to reduce the file size but it could not be done without a higher increase of code.
That is why I have started to count the time required for some blocks of code to complete.
Fine tunning has begun...
...and, as a result, the time required to load and process that file is now under one second !
The easiest way is to use the GetTickCount function:
DWORD startTime, endTime; DWORD elapsedTime; startTime = GetTickCount(); // ... the code for which we want to measure the time required to work must be here ... endTime = GetTickCount(); elapsedTime = endTime - startTime;
Warning: About the code
The code presented above is written with the intention to be as clear as possible. Do not consider it as THE way, or my way, to write code.
Note: About the GetTickCount function
The GetTickCount function returns the elapsed time since the system was started. The value is in miliseconds. The resolution is limited to the resolution of the system timer.
Because the result is stored as DWORD the value will overflow after ~49.7 days.
Using this method I have put together some lines of code for an application to be used for time measurements.
First I have made a function that runs the tests. The function has been called 25 times.
Each test was called 10 thousands times.
// somewhere in the program: int i; for(i=0; i<25; i++) RunTheTests(); // ... // a simple test function void Test1(void) { int i; for(i=0; i<10000; i++){ // ... the code for which we want to measure the time required to work must be here ... } } // this function computes the elapsed time and display the result void ComputeAndDisplayElapsedTime(DWORD sTime, DWORD eTime) { // the code has been omitted for simplicity } // the function that runs the tests void RunTheTests(void) { DWORD startTime, endTime; startTime = GetTickCount(); Test1(); endTime = GetTickCount(); ComputeAndDisplayElapsedTime(startTime, endTime); startTime = GetTickCount(); Test2(); endTime = GetTickCount(); ComputeAndDisplayElapsedTime(startTime, endTime); startTime = GetTickCount(); Test3(); endTime = GetTickCount(); ComputeAndDisplayElapsedTime(startTime, endTime); // ... and so on ... }
Note
The actual code used was a little more complicated then the one presented above. The purpose of the previous code is to show you the principles that I have used.
In the next three paragraphs I will present you some of the results related to the usage of the CString class.
Tested code A:
void TestA(void) { CString s1, s2, s3; int i; for(i=0; i<10000; i++){ s3 = _T("alfa"); s1 = s3 + _T("beta"); s2 = s3 + _T("gamma"); } }Tested code B:
void TestB(void) { CString s1, s2; int i; for(i=0; i<10000; i++){ s1 = _T("alfa"); s2 = s1; s1 += _T("beta"); s2 += _T("gamma"); } }
Result: code A is 170 percent slower compared with code B.
Tested code A:
void TestA(void) { CString str; int i; for(i=0; i<10000; i++){ str = _T("123456789abcd"); str = str.Mid(9); } }Tested code B:
void TestB(void) { CString str; LPCSTR alfa; int i; for(i=0; i<10000; i++){ str = _T("123456789abcd"); alfa = str; str = &alfa[9]; } }
Result: code A is 349 percent slower compared with code B.
Tested code A:
void TestA(void) { CString str, s1, s2; int i; for(i=0; i<10000; i++){ str = _T("1234-1234-1234"); s1 = str.Mid(4, 1); s2 = str.Mid(9, 1); if(s1==s2){ i = i; } } }Tested code B:
void TestB(void) { CString str, s1, s2; int i; for(i=0; i<10000; i++){ str = _T("1234-1234-1234"); s1 = str.Mid(4, 1); s2 = str.Mid(9, 1); if(s1.Compare(s2)==0){ i = i; } } }Tested code C:
void TestC(void) { CString str, s1, s2; int i; for(i=0; i<10000; i++){ str = _T("1234-1234-1234"); s1 = str.Mid(4, 1); s2 = str.Mid(9, 1); if(s1.CompareNoCase(s2)==0){ i = i; } } }Tested code D:
void TestD(void) { CString str; LPCSTR alfa; int i; for(i=0; i<10000; i++){ str = _T("1234-1234-1234"); alfa = str; if(alfa[4]==alfa[9]){ i = i; } } }
Results:
Code A is 964 percent slower compared with code D.
Code B is 973 percent slower compared with code D.
Code C is 968 percent slower compared with code D.
By comparing the result it is easy to see how you can get a speed boost by using a method instead another.
This document is intended to open your eyes to this phase of programming applications: increasing the quality
of your final work by increasing the speed of code without loosing functionality.
This document is copyrighted (c) 2006 by Calin Radoni. Permission is granted to copy and/or distribute this document.
No liability for the contents of this document can be accepted. Use the concepts, examples and information at your own risk. There may be errors and inaccuracies that could be damaging to your system. Proceed with caution, the author do not take any responsibility.
All copyrights are held by their respective owners, unless specifically noted otherwise. Use of a term in this document should not be regarded as affecting the validity of any trademark or service mark. Naming of particular products or brands should not be seen as endorsements.