2000-03-14 18:56:34 +03:00
// profile_main.cpp
# include "nscore.h"
2000-03-25 03:56:47 +03:00
# include <iostream.h>
2000-03-14 18:56:34 +03:00
# include <string>
# include <iomanip>
2000-03-29 12:14:09 +04:00
# include "nsInt64.h"
2000-03-25 04:59:19 +03:00
# ifdef XP_MAC
2000-03-29 12:14:09 +04:00
# include <Timer.h>
2000-03-22 11:22:28 +03:00
# include "Profiler.h"
2000-03-29 12:14:09 +04:00
# else
# include "prtime.h"
2000-03-25 04:59:19 +03:00
# endif
2000-03-22 11:22:28 +03:00
2000-03-14 18:56:34 +03:00
# ifndef TEST_STD_STRING
# include "nsString.h"
# else
# include "nsStdStringWrapper.h"
typedef nsStdCString nsCString ;
# endif
static const int kTestSucceeded = 0 ;
static const int kTestFailed = 1 ;
2000-03-25 03:56:47 +03:00
static const size_t N = 100000 ;
2000-03-22 11:22:28 +03:00
2000-03-14 18:56:34 +03:00
template < class T >
inline
PRUint32
TotalLength ( const T & s )
{
return s . Length ( ) ;
}
2000-03-22 11:22:28 +03:00
NS_SPECIALIZE_TEMPLATE
2000-03-14 18:56:34 +03:00
inline
PRUint32
TotalLength ( const string & s )
{
return s . length ( ) ;
}
template < class T >
inline
PRUint32
Find ( const T & text , const T & pattern )
{
return text . Find ( pattern ) ;
}
2000-03-22 11:22:28 +03:00
NS_SPECIALIZE_TEMPLATE
2000-03-14 18:56:34 +03:00
inline
PRUint32
Find ( const string & text , const string & pattern )
{
return text . find ( pattern ) ;
}
inline
2000-03-29 12:14:09 +04:00
nsInt64
GetTime ( )
2000-03-14 18:56:34 +03:00
{
2000-03-29 12:14:09 +04:00
# ifdef XP_MAC
UnsignedWide time ;
Microseconds ( & time ) ;
return nsInt64 ( * reinterpret_cast < PRInt64 * > ( & time ) ) ;
# else
return nsInt64 ( PR_Now ( ) ) ;
2000-03-25 04:59:19 +03:00
# endif
2000-03-29 12:14:09 +04:00
}
2000-03-14 18:56:34 +03:00
class TestTimer
{
public :
2000-03-29 12:14:09 +04:00
TestTimer ( ) : mStartTime ( GetTime ( ) ) { }
2000-03-14 18:56:34 +03:00
~ TestTimer ( )
{
2000-03-29 12:14:09 +04:00
nsInt64 stopTime = GetTime ( ) ;
nsInt64 totalTime = stopTime - mStartTime ;
2000-03-25 08:44:57 +03:00
# ifdef HAVE_LONG_LONG
2000-03-29 12:14:09 +04:00
cout < < setw ( 10 ) < < NS_STATIC_CAST ( PRInt64 , totalTime ) < < " <20> s : " ;
2000-03-25 08:44:57 +03:00
# else
2000-03-29 12:14:09 +04:00
cout < < setw ( 10 ) < < NS_STATIC_CAST ( PRInt32 , totalTime ) < < " <EFBFBD> s : " ;
2000-03-25 08:44:57 +03:00
# endif
2000-03-14 18:56:34 +03:00
}
private :
2000-03-29 12:14:09 +04:00
nsInt64 mStartTime ;
2000-03-14 18:56:34 +03:00
} ;
2000-04-04 09:20:05 +04:00
inline
int
foo ( const nsCString & )
{
return 1 ;
}
static
int
test_construction ( )
{
cout < < endl ;
{
nsCString someCString ;
int total = 0 ;
TestTimer timer ;
for ( int i = 0 ; i < N ; + + i )
{
total + = foo ( someCString ) ;
}
}
cout < < " null loop time for constructor " < < endl ;
{
int total = 0 ;
TestTimer timer ;
for ( int i = 0 ; i < N ; + + i )
{
total + = foo ( nsCString ( ) ) ;
}
}
cout < < " nsCString() " < < endl ;
{
int total = 0 ;
TestTimer timer ;
for ( int i = 0 ; i < N ; + + i )
{
total + = foo ( nsCString ( " This is a reasonable length string with some text in it and it is good. " ) ) ;
}
}
cout < < " nsCString( \" abc \" ) " < < endl ;
return kTestSucceeded ;
}
2000-03-14 18:56:34 +03:00
static
int
test_concat ( )
{
2000-04-04 09:20:05 +04:00
cout < < endl ;
2000-03-14 18:56:34 +03:00
//---------|---------|---------|---------|---------|---------|---------|
nsCString s1 ( " This is a reasonable length string with some text in it and it is good. " ) ;
nsCString s2 ( " This is another string that I will use in the concatenation test. " ) ;
nsCString s3 ( " This is yet a third string that I will use in the concatenation test. " ) ;
PRUint32 len = TotalLength ( s1 + s2 + s3 + s1 + s2 + s3 ) ;
if ( len ! = ( 71 + 65 + 69 + 71 + 65 + 69 ) )
{
cout < < " |test_concat()| FAILED " < < endl ;
return kTestFailed ;
}
2000-04-04 09:20:05 +04:00
{
nsCString anEmptyCString ;
TestTimer timer ;
for ( int i = 0 ; i < N ; + + i )
{
len + = TotalLength ( anEmptyCString ) ;
}
}
cout < < " null loop time for concat " < < endl ;
2000-03-14 18:56:34 +03:00
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
len + = TotalLength ( s1 + s2 + s3 + s1 + s2 + s3 ) ;
}
cout < < " TotalLength( s1 + s2 + s3 + s1 + s2 + s3 ) " < < endl ;
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
len + = TotalLength ( s1 + s2 ) ;
}
cout < < " TotalLength( s1 + s2 ) " < < endl ;
return kTestSucceeded ;
}
static
int
test_concat_and_assign ( )
{
//---------|---------|---------|---------|---------|---------|---------|
nsCString s1 ( " This is a reasonable length string with some text in it and it is good. " ) ;
nsCString s2 ( " This is another string that I will use in the concatenation test. " ) ;
nsCString s3 ( " This is yet a third string that I will use in the concatenation test. " ) ;
nsCString s4 = s1 + s2 + s3 + s1 + s2 + s3 ;
if ( TotalLength ( s4 ) ! = ( 71 + 65 + 69 + 71 + 65 + 69 ) )
{
cout < < " |test_concat()| FAILED " < < endl ;
return kTestFailed ;
}
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
s4 = s1 + s2 + s3 + s1 + s2 + s3 ;
}
cout < < " s4 = s1 + s2 + s3 + s1 + s2 + s3 " < < endl ;
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
s4 = s1 + s2 ;
}
cout < < " s4 = s1 + s2 " < < endl ;
return kTestSucceeded ;
}
static
int
test_compare ( )
{
2000-03-22 11:22:28 +03:00
nsCString s1 ( " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxThis is a reasonable length string with some text in it and it is good. " ) ;
nsCString s2 ( " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxThis is a reasonable length string with some text in it and it is bad. " ) ;
2000-03-14 18:56:34 +03:00
int count = 0 ;
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
if ( s1 > s2 )
+ + count ;
}
cout < < " s1 > s2 " < < endl ;
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
if ( s1 = = s1 )
+ + count ;
}
cout < < " s1 == s1 " < < endl ;
return kTestSucceeded ;
}
static
int
test_countchar ( )
{
nsCString s1 ( " This is a reasonable length string with some text in it and it is good. " ) ;
if ( s1 . CountChar ( ' e ' ) ! = 5 )
{
cout < < " |test_countchar()| FAILED: found a count of " < < s1 . CountChar ( ' e ' ) < < endl ;
return kTestFailed ;
}
PRUint32 total = 0 ;
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
total + = s1 . CountChar ( ' e ' ) ;
}
cout < < " s1.CountChar('e') " < < endl ;
return kTestSucceeded ;
}
static
int
test_append_string ( )
{
nsCString s1 ( " This is a reasonable length string with some text in it and it is good. " ) ;
nsCString s2 ( " This is another string that I will use in the concatenation test. " ) ;
PRUint32 len = 0 ;
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
{
nsCString s3 ;
s3 . Append ( s1 ) ;
s3 . Append ( s2 ) ;
len + = TotalLength ( s3 ) ;
}
}
cout < < " s3.Append(s1); s3.Append(s2) " < < endl ;
return kTestSucceeded ;
}
static
int
test_repeated_append_string ( )
{
nsCString s1 ( " This is a reasonable length string with some text in it and it is good. " ) ;
nsCString s2 ( " This is another string that I will use in the concatenation test. " ) ;
PRUint32 len = 0 ;
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
{
nsCString s3 ;
for ( int j = 0 ; j < 100 ; + + j )
{
s3 . Append ( s1 ) ;
s3 . Append ( s2 ) ;
len + = TotalLength ( s3 ) ;
}
}
}
cout < < " repeated s3.Append(s1); s3.Append(s2) " < < endl ;
return kTestSucceeded ;
}
2000-04-04 09:20:05 +04:00
static
int
test_append_char ( )
{
cout < < endl ;
PRUint32 len = 0 ;
nsCString s1 ( " hello " ) ;
PRUint32 oldLength = s1 . Length ( ) ;
{
TestTimer timer ;
for ( int i = 0 ; i < N ; + + i )
{
s1 . SetLength ( oldLength ) ;
}
}
cout < < " null loop time for append char " < < endl ;
{
TestTimer timer ;
for ( int i = 0 ; i < N ; + + i )
{
s1 . Append ( ' e ' ) ;
s1 . SetLength ( oldLength ) ;
}
}
cout < < " s1.Append('e') " < < endl ;
return kTestSucceeded ;
}
2000-03-14 18:56:34 +03:00
static
int
test_repeated_append_char ( )
{
PRUint32 len = 0 ;
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
{
nsCString s1 ;
for ( int j = 0 ; j < 1000 ; + + j )
{
2000-03-31 11:28:38 +04:00
s1 . Append ( ' e ' ) ;
2000-03-14 18:56:34 +03:00
len + = TotalLength ( s1 ) ;
}
}
}
cout < < " repeated s1.Append('e') " < < endl ;
return kTestSucceeded ;
}
static
int
test_insert_string ( )
{
nsCString s1 ( " This is a reasonable length string with some text in it and it is good. " ) ;
PRUint32 len = 0 ;
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
{
nsCString s2 ( " This is another string that I will use in the concatenation test. " ) ;
s2 . Insert ( s1 , 3 ) ;
len + = TotalLength ( s2 ) ;
}
}
cout < < " s2.Insert(s1, 3) " < < endl ;
return kTestSucceeded ;
}
2000-04-04 09:20:05 +04:00
# ifndef TEST_STD_STRING
2000-03-14 18:56:34 +03:00
static
int
test_find_string ( )
{
nsCString text ( " aaaaaaaaaab " ) ;
nsCString pattern ( " aab " ) ;
PRUint32 position = 0 ;
{
TestTimer timer ;
2000-03-22 11:22:28 +03:00
for ( int i = 0 ; i < N ; + + i )
2000-03-14 18:56:34 +03:00
position = Find ( text , pattern ) ;
}
cout < < " text.Find(pattern) " < < endl ;
return kTestSucceeded ;
}
# endif
2000-03-22 11:22:28 +03:00
class Profiler
{
public :
Profiler ( )
{
#if 0
ProfilerInit ( collectDetailed , bestTimeBase , 100 , 32 ) ;
# endif
}
2000-03-25 04:59:19 +03:00
void
Dump ( const char * output_name )
{
}
2000-03-22 11:22:28 +03:00
void
Dump ( const unsigned char * output_name )
{
#if 0
ProfilerDump ( output_name ) ;
# endif
}
~ Profiler ( )
{
#if 0
ProfilerDump ( mOutputName ) ;
ProfilerTerm ( ) ;
# endif
}
} ;
2000-03-14 18:56:34 +03:00
int
main ( )
{
2000-03-22 11:22:28 +03:00
2000-03-14 18:56:34 +03:00
cout < < " String performance profiling. Compiled " __DATE__ " " __TIME__ < < endl ;
# ifdef TEST_STD_STRING
cout < < " Testing std::string. " < < endl ;
# elif defined(NEW_STRING_APIS)
cout < < " Testing factored nsString. " < < endl ;
# else
cout < < " Testing raw nsString. " < < endl ;
# endif
int tests_failed = 0 ;
2000-03-22 11:22:28 +03:00
Profiler profiler ;
2000-04-04 09:20:05 +04:00
tests_failed + = test_construction ( ) ;
2000-03-14 18:56:34 +03:00
tests_failed + = test_concat ( ) ;
2000-05-12 09:18:36 +04:00
tests_failed + = test_concat_and_assign ( ) ;
2000-03-14 18:56:34 +03:00
tests_failed + = test_compare ( ) ;
tests_failed + = test_countchar ( ) ;
tests_failed + = test_append_string ( ) ;
tests_failed + = test_repeated_append_string ( ) ;
2000-04-04 09:20:05 +04:00
tests_failed + = test_append_char ( ) ;
2000-05-12 09:18:36 +04:00
tests_failed + = test_repeated_append_char ( ) ;
2000-03-14 18:56:34 +03:00
tests_failed + = test_insert_string ( ) ;
2000-04-04 09:20:05 +04:00
# ifndef TEST_STD_STRING
tests_failed + = test_find_string ( ) ;
# endif
2000-03-14 18:56:34 +03:00
2000-03-22 11:22:28 +03:00
# ifdef TEST_STD_STRING
profiler . Dump ( " \ pStandard String.prof " ) ;
# elif defined(NEW_STRING_APIS)
profiler . Dump ( " \ pFactored String.prof " ) ;
# else
profiler . Dump ( " \ pRaw String.prof " ) ;
# endif
2000-03-14 18:56:34 +03:00
if ( tests_failed )
cout < < " One or more tests FAILED. Measurements may be invalid. " < < endl ;
cout < < " End of string performance profiling. " < < endl ;
return 0 ;
}