Back to index

lightning-sunbird  0.9+nobinonly
profile_main.cpp
Go to the documentation of this file.
00001 // profile_main.cpp
00002 
00003 #include "nscore.h"
00004 #include <iostream.h>
00005 #include <string>
00006 #include <iomanip>
00007 
00008 #include "nsInt64.h"
00009 
00010 #ifdef XP_MAC
00011 #include <Timer.h>
00012 #include "Profiler.h"
00013 #else
00014 #include "prtime.h"
00015 #endif
00016 
00017 #ifndef TEST_STD_STRING
00018 #include "nsString.h"
00019 #else
00020 #include "nsStdStringWrapper.h"
00021 typedef nsStdCString nsCString;
00022 #endif
00023 
00024 static const int kTestSucceeded = 0;
00025 static const int kTestFailed = 1;
00026 
00027 static const size_t N = 100000;
00028 
00029 
00030 template <class T>
00031 inline
00032 PRUint32
00033 TotalLength( const T& s )
00034   {
00035     return s.Length();
00036   }
00037 
00038 NS_SPECIALIZE_TEMPLATE
00039 inline
00040 PRUint32
00041 TotalLength( const string& s )
00042   {
00043     return s.length();
00044   }
00045 
00046 template <class T>
00047 inline
00048 PRUint32
00049 Find( const T& text, const T& pattern )
00050   {
00051     return text.Find(pattern);
00052   }
00053 
00054 NS_SPECIALIZE_TEMPLATE
00055 inline
00056 PRUint32
00057 Find( const string& text, const string& pattern )
00058   {
00059     return text.find(pattern);
00060   }
00061 
00062 inline
00063 nsInt64
00064 GetTime()
00065   {
00066 #ifdef XP_MAC
00067     UnsignedWide time;
00068     Microseconds(&time);
00069     return nsInt64( *reinterpret_cast<PRInt64*>(&time) );
00070 #else
00071     return nsInt64( PR_Now() );
00072 #endif
00073   }
00074 
00075 class TestTimer
00076   {
00077     public:
00078       TestTimer() : mStartTime(GetTime()) { }
00079 
00080      ~TestTimer()
00081         {
00082           nsInt64 stopTime = GetTime();
00083                nsInt64 totalTime = stopTime - mStartTime;
00084 #ifdef HAVE_LONG_LONG
00085           cout << setw(10) << NS_STATIC_CAST(PRInt64, totalTime) << " Ás : ";
00086 #else
00087           cout << setw(10) << NS_STATIC_CAST(PRInt32, totalTime) << "Ás : ";
00088 #endif
00089         }
00090 
00091     private:
00092       nsInt64 mStartTime;
00093   };
00094 
00095 inline
00096 int
00097 foo( const nsCString& )
00098   {
00099     return 1;
00100   }
00101 
00102 static
00103 int
00104 test_construction()
00105   {
00106     cout << endl;
00107 
00108     {
00109       nsCString someCString;
00110       int total = 0;
00111       TestTimer timer;
00112       for ( int i=0; i<N; ++i )
00113         {
00114           total += foo( someCString );
00115         }
00116     }
00117     cout << "null loop time for constructor" << endl;
00118 
00119 
00120     {
00121       int total = 0;
00122       TestTimer timer;
00123       for ( int i=0; i<N; ++i )
00124         {
00125           total += foo( nsCString() );
00126         }
00127     }
00128     cout << "nsCString()" << endl;
00129 
00130 
00131     {
00132       int total = 0;
00133       TestTimer timer;
00134       for ( int i=0; i<N; ++i )
00135         {
00136           total += foo( nsCString("This is a reasonable length string with some text in it and it is good.") );
00137         }
00138     }
00139     cout << "nsCString(\"abc\")" << endl;
00140 
00141     return kTestSucceeded;
00142   }
00143 
00144 static
00145 int
00146 test_concat()
00147   {
00148     cout << endl;
00149 
00150                 //---------|---------|---------|---------|---------|---------|---------|
00151     nsCString s1("This is a reasonable length string with some text in it and it is good.");
00152     nsCString s2("This is another string that I will use in the concatenation test.");
00153     nsCString s3("This is yet a third string that I will use in the concatenation test.");
00154 
00155     PRUint32 len = TotalLength( s1 + s2 + s3 + s1 + s2 + s3 );
00156     if ( len != (71 + 65 + 69 + 71 + 65 + 69) )
00157       {
00158         cout << "|test_concat()| FAILED" << endl;
00159         return kTestFailed;
00160       }
00161 
00162 
00163     {
00164       nsCString anEmptyCString;
00165       TestTimer timer;
00166       for ( int i=0; i<N; ++i )
00167         {
00168           len += TotalLength( anEmptyCString );
00169         }
00170     }
00171     cout << "null loop time for concat" << endl;
00172 
00173 
00174     {
00175       TestTimer timer;
00176       for ( int i=0; i<N; ++i )
00177         len += TotalLength( s1 + s2 + s3 + s1 + s2 + s3 );
00178     }
00179     cout << "TotalLength( s1 + s2 + s3 + s1 + s2 + s3 )" << endl;
00180 
00181 
00182     {
00183       TestTimer timer;
00184       for ( int i=0; i<N; ++i )
00185         len += TotalLength( s1 + s2 );
00186     }
00187     cout << "TotalLength( s1 + s2 )" << endl;
00188 
00189     return kTestSucceeded;
00190   }
00191 
00192 static
00193 int
00194 test_concat_and_assign()
00195   {
00196                 //---------|---------|---------|---------|---------|---------|---------|
00197     nsCString s1("This is a reasonable length string with some text in it and it is good.");
00198     nsCString s2("This is another string that I will use in the concatenation test.");
00199     nsCString s3("This is yet a third string that I will use in the concatenation test.");
00200 
00201     nsCString s4( s1 + s2 + s3 + s1 + s2 + s3 );
00202     if ( TotalLength(s4) != (71 + 65 + 69 + 71 + 65 + 69) )
00203       {
00204         cout << "|test_concat()| FAILED" << endl;
00205         return kTestFailed;
00206       }
00207 
00208 
00209     {
00210       TestTimer timer;
00211       for ( int i=0; i<N; ++i )
00212         s4 = s1 + s2 + s3 + s1 + s2 + s3;
00213     }
00214     cout << "s4 = s1 + s2 + s3 + s1 + s2 + s3" << endl;
00215 
00216     {
00217       TestTimer timer;
00218       for ( int i=0; i<N; ++i )
00219         s4 = s1 + s2;
00220     }
00221     cout << "s4 = s1 + s2" << endl;
00222 
00223     return kTestSucceeded;
00224   }
00225 
00226 static
00227 int
00228 test_compare()
00229   {
00230     nsCString s1("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxThis is a reasonable length string with some text in it and it is good.");
00231     nsCString s2("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxThis is a reasonable length string with some text in it and it is bad.");
00232 
00233     int count = 0;
00234     {
00235       TestTimer timer;
00236       for ( int i=0; i<N; ++i )
00237         if ( s1 > s2 )
00238           ++count;
00239     }
00240     cout << "s1 > s2" << endl;
00241 
00242     {
00243       TestTimer timer;
00244       for ( int i=0; i<N; ++i )
00245         if ( s1 == s1 )
00246           ++count;
00247     }
00248     cout << "s1 == s1" << endl;
00249 
00250     return kTestSucceeded;
00251   }
00252 
00253 static
00254 int
00255 test_countchar()
00256   {
00257     nsCString s1("This is a reasonable length string with some text in it and it is good.");
00258 
00259     if ( s1.CountChar('e') != 5 )
00260       {
00261         cout << "|test_countchar()| FAILED: found a  count of " << s1.CountChar('e') << endl;
00262         return kTestFailed;
00263       }
00264 
00265     PRUint32 total = 0;
00266     {
00267       TestTimer timer;
00268       for ( int i=0; i<N; ++i )
00269         total += s1.CountChar('e');
00270     }
00271     cout << "s1.CountChar('e')" << endl;
00272 
00273     return kTestSucceeded;
00274   }
00275 
00276 static
00277 int
00278 test_append_string()
00279   {
00280     nsCString s1("This is a reasonable length string with some text in it and it is good.");
00281     nsCString s2("This is another string that I will use in the concatenation test.");
00282 
00283     PRUint32 len = 0;
00284     
00285     {
00286       TestTimer timer;
00287       for ( int i=0; i<N; ++i )
00288         {
00289           nsCString s3;
00290           s3.Append(s1);
00291           s3.Append(s2);
00292           len += TotalLength(s3);
00293         }
00294     }
00295     cout << "s3.Append(s1); s3.Append(s2)" << endl;
00296 
00297     return kTestSucceeded;
00298   }
00299 
00300 static
00301 int
00302 test_repeated_append_string()
00303   {
00304     nsCString s1("This is a reasonable length string with some text in it and it is good.");
00305     nsCString s2("This is another string that I will use in the concatenation test.");
00306 
00307     PRUint32 len = 0;
00308     
00309     {
00310       TestTimer timer;
00311       for ( int i=0; i<N; ++i )
00312         {
00313           nsCString s3;
00314           for ( int j=0; j<100; ++j )
00315             {
00316               s3.Append(s1);
00317               s3.Append(s2);
00318               len += TotalLength(s3);
00319             }
00320         }
00321     }
00322     cout << "repeated s3.Append(s1); s3.Append(s2)" << endl;
00323 
00324     return kTestSucceeded;
00325   }
00326 
00327 static
00328 int
00329 test_append_char()
00330   {
00331     cout << endl;
00332 
00333     PRUint32 len = 0;
00334 
00335     nsCString s1("hello");
00336     PRUint32 oldLength = s1.Length();
00337     
00338     {
00339       TestTimer timer;
00340       for ( int i=0; i<N; ++i )
00341         {
00342           s1.SetLength(oldLength);
00343         }
00344     }
00345     cout << "null loop time for append char" << endl;
00346 
00347     {
00348       TestTimer timer;
00349       for ( int i=0; i<N; ++i )
00350         {
00351           s1.Append('e');
00352           s1.SetLength(oldLength);
00353         }
00354     }
00355     cout << "s1.Append('e')" << endl;
00356 
00357     return kTestSucceeded;
00358   }
00359 
00360 static
00361 int
00362 test_repeated_append_char()
00363   {
00364     PRUint32 len = 0;
00365     
00366     {
00367       TestTimer timer;
00368       for ( int i=0; i<N; ++i )
00369         {
00370           nsCString s1;
00371           for ( int j=0; j<1000; ++j )
00372             {
00373               s1.Append('e');
00374               len += TotalLength(s1);
00375             }
00376         }
00377     }
00378     cout << "repeated s1.Append('e')" << endl;
00379 
00380     return kTestSucceeded;
00381   }
00382 
00383 static
00384 int
00385 test_insert_string()
00386   {
00387     nsCString s1("This is a reasonable length string with some text in it and it is good.");
00388 
00389     PRUint32 len = 0;
00390     
00391     {
00392       TestTimer timer;
00393       for ( int i=0; i<N; ++i )
00394         {
00395           nsCString s2("This is another string that I will use in the concatenation test.");
00396           s2.Insert(s1, 3);
00397           len += TotalLength(s2);
00398         }
00399     }
00400     cout << "s2.Insert(s1, 3)" << endl;
00401 
00402     return kTestSucceeded;
00403   }
00404 
00405 #ifndef TEST_STD_STRING
00406 static
00407 int
00408 test_find_string()
00409   {
00410     nsCString text("aaaaaaaaaab");
00411     nsCString pattern("aab");
00412 
00413     PRUint32 position = 0;
00414     {
00415       TestTimer timer;
00416       for ( int i=0; i<N; ++i )
00417         position = Find(text, pattern);
00418     }
00419     cout << "text.Find(pattern)" << endl;
00420 
00421     return kTestSucceeded;
00422   }
00423 #endif
00424 
00425 class Profiler
00426   {
00427     public:
00428       Profiler()
00429         {
00430 #if 0
00431           ProfilerInit(collectDetailed, bestTimeBase, 100, 32);
00432 #endif
00433         }
00434 
00435       void
00436       Dump( const char* output_name )
00437         {
00438        }
00439 
00440       void
00441       Dump( const unsigned char* output_name )
00442         {
00443 #if 0
00444           ProfilerDump(output_name);
00445 #endif
00446         }
00447 
00448      ~Profiler()
00449         {
00450 #if 0
00451           ProfilerDump(mOutputName);
00452           ProfilerTerm();
00453 #endif
00454         }
00455   };
00456 
00457 int
00458 main()
00459   {
00460 
00461     cout << "String performance profiling.  Compiled " __DATE__ " " __TIME__ << endl;
00462 #ifdef TEST_STD_STRING
00463     cout << "Testing std::string." << endl;
00464 #else
00465     cout << "Testing factored nsString." << endl;
00466 #endif
00467 
00468     int tests_failed = 0;
00469 
00470     Profiler profiler;
00471 
00472     tests_failed += test_construction();
00473     tests_failed += test_concat();
00474     tests_failed += test_concat_and_assign();
00475     tests_failed += test_compare();
00476     tests_failed += test_countchar();
00477     tests_failed += test_append_string();
00478     tests_failed += test_repeated_append_string();
00479     tests_failed += test_append_char();
00480     tests_failed += test_repeated_append_char();
00481     tests_failed += test_insert_string();
00482 #ifndef TEST_STD_STRING
00483     tests_failed += test_find_string();
00484 #endif
00485 
00486 #ifdef TEST_STD_STRING
00487     profiler.Dump("\pStandard String.prof");
00488 #else
00489     profiler.Dump("\pFactored String.prof");
00490 #endif
00491 
00492     if ( tests_failed )
00493       cout << "One or more tests FAILED.  Measurements may be invalid." << endl;
00494 
00495     cout << "End of string performance profiling." << endl;
00496     return 0;
00497   }