#include #include "getCurrentTime.h" #include #include #include #include #include #if defined( _MSC_VER ) #pragma intrinsic (memcpy,memcmp,memset,strcat,strcmp,strcpy,strlen) #endif namespace constructor { void * operator new( size_t count, void * object ) { return object; } } //#define ALLOC_AT_ONCE //#define USE_MALLOC // TEMPLATE CLASS allocator template class fast_allocator #ifndef USE_MALLOC : public std::allocator #endif { char memory[N]; #ifndef ALLOC_AT_ONCE char* marker; #endif public: typedef std::allocator MyBase; typedef T value_type; typedef value_type *pointer; typedef value_type & reference; typedef const value_type *const_pointer; typedef const value_type & const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind { // convert an allocator<_Ty> to an allocator <_Other> typedef fast_allocator<_Other,N> other; }; // return address of mutable _Val pointer address(reference _Val) const { return (&_Val); } const_pointer address(const_reference _Val) const { // return address of nonmutable _Val return (&_Val); } fast_allocator() throw() #ifndef ALLOC_AT_ONCE : marker( memory ) #endif {} // construct by copying (do nothing) fast_allocator( const fast_allocator& ) throw() #ifndef ALLOC_AT_ONCE : marker( memory ) #endif {} // construct from a related allocator (do nothing) // template // allocatorN(const std::allocator<_Other>&) throw() // : marker( memory ) // {} // deallocate object at _Ptr, ignore size void deallocate(pointer p, size_type n ) { #ifdef ALLOC_AT_ONCE if ( p != static_cast(memory) ) #ifdef USE_MALLOC free( p ); #else return MyBase::deallocate( p, n ); #endif #else/*ALLOC_AT_ONCE*/ if ( p+n == marker ) marker = p; else if ( p < static_cast(memory) || static_cast(&memory[N]) <= p ) #ifdef USE_MALLOC free( p ); #else return MyBase::deallocate( p, n ); #endif #endif } // allocate array of n elements pointer allocate(size_type nCount) { register size_type s = sizeof(T)*nCount; #ifdef ALLOC_AT_ONCE if ( sizeof(T)*nCount < N ) return static_cast(memory); #else if ( sizeof(T)*nCount < (&memory[N] - marker) ) { pointer p = static_cast(marker); marker += s; return p; } #endif else #ifdef USE_MALLOC return static_cast(malloc( s )); #else return MyBase::allocate( nCount ); #endif } // allocate array of n elements, ignore hint pointer allocate(size_type nCount, const void *) { return allocate(nCount); } // construct object at _Ptr with value _Val void construct(pointer _Ptr, const T& _Val) { ::new (_Ptr) T(_Val); } // destroy object at _Ptr void destroy( pointer p ) { p->~T(); } // estimate maximum array size size_type max_size() const throw() { #ifdef USE_MALLOC return (size_type)(-1) / sizeof(T); #else // return MyBase::max_size(); return (int)(-1) / sizeof(T); #endif } // bool operator( const fast_allocator& op ) // { // return &op == this; // } }; template inline bool operator== ( const fast_allocator& op1, const fast_allocator& op2 ) { return &op1 == &op2; } // STRUCT char_traits (FROM ) template struct fast_char_traits { // properties of a string or stream char element typedef C char_type; typedef int int_type; typedef std::streampos pos_type; typedef std::streamoff off_type; // typedef _Mbstatet state_type; // assign an element static void assign( char_type& l, const char_type& r) { l = r; } // test for element equality static bool eq( const char_type& l, const char_type& r) { return (l == r); } // test if l precedes r static bool lt( const char_type& l, const char_type& r) { return (l < r); } // compare [_First1, _First1 + n) with [_First2, ...) static int compare(const char_type *op1, const char_type *op2, size_t n) { return (::memcmp(op1, op2, n*sizeof(char_type))); } // find length of null-terminated string static size_t length(const char_type * op) { return (::strlen(op)); } // assume there is enough space in the destination buffer static char_type * copy(char_type *dest, const char_type *src, size_t n) { return reinterpret_cast(::memcpy( dest, src, n*sizeof(char_type) )); } // look for _Ch in [_First, _First + n) static const char_type * find(const char_type * src, size_t n, const char_type& ch) { return ((const char_type *)::memchr(src, ch, n)); } // move [_First1, _First1 + n) to [_First2, ...) // assume there is enough space in the destination buffer static char_type * move(char_type *dest, const char_type *src, size_t n) { return reinterpret_cast(::memmove(dest, src, n*sizeof(char_type))); } // assign n * _Ch to [_First, ...) static char_type * assign(char_type *_First, size_t n, char_type _Ch) { return ((char_type *)::memset(_First, _Ch, n)); } // convert metacharacter to character static char_type to_char_type(const int_type& chMeta) { return ((char_type)chMeta); } // convert character to metacharacter static int_type to_int_type(const char_type& ch) { return ((unsigned char)ch); } // test for metacharacter equality static bool eq_int_type(const int_type& l, const int_type& r) { return (l == r); } // return end-of-file metacharacter static int_type eof() { return (EOF); } // return anything but EOF static int_type not_eof(const int_type& chMeta) { return (chMeta != eof() ? chMeta : !eof()); } }; template < class CharType, class Traits=fast_char_traits, class Allocator=fast_allocator > class fast_basic_string : public std::basic_string< CharType, Traits, Allocator > { public: typedef fast_basic_string< CharType, Traits, Allocator > MySelf; typedef std::basic_string< CharType, Traits, Allocator > MyBase; fast_basic_string( const typename MyBase::value_type* _Ptr, typename MyBase::size_type _Count, const typename MyBase::allocator_type& _Al = Allocator ( ) ) : std::basic_string< CharType, Traits, Allocator >( _Ptr, _Count, _Al ) {} fast_basic_string( const typename MyBase::value_type* _Ptr, const typename MyBase::allocator_type& _Al = Allocator ( ) ) : std::basic_string< CharType, Traits, Allocator >( _Ptr, _Al ) {} fast_basic_string( const MyBase& _Right, typename MyBase::size_type _Roff = 0, typename MyBase::size_type _Count = npos, const typename MyBase::allocator_type& _Al = Allocator ( ) ) : std::basic_string< CharType, Traits, Allocator >( _Right, _Roff, _Count, _Al ) {} fast_basic_string( typename MyBase::size_type _Count, typename MyBase::value_type _Ch, const typename MyBase::allocator_type& _Al = Allocator ( ) ) : std::basic_string< CharType, Traits, Allocator >( _Count, _Ch, _Al ) {} explicit fast_basic_string( const typename MyBase::allocator_type& _Al = Allocator ( ) ) : std::basic_string< CharType, Traits, Allocator >( _Al ) {} #if 0 //ndef _MSC_VER bool operator == ( const MySelf& str ) { return ( str.size() != size() ) ? false : MyBase::operator == ( str ); } #endif }; #if 1 //def _MSC_VER template inline bool operator==( const fast_basic_string& l, const fast_basic_string& r ) { // test for string equality return (l.size() != r.size()) ? false : (l.compare(r) == 0); } #endif typedef fast_basic_string< char > fast_string; const char* testStr[] = { "1", //1 "12", //2 "123", //3 "1234", //4 "12345", //5 "123456", //6 "1234567", //7 "12345678", //8 "123456781", //9 "1234567812", //10 "12345678123", //11 "123456781234", //12 "1234567812345", //13 "12345678123456", //14 "123456781234567", //15 "1234567812345678", //16 "12345678123456781", //17 "123456781234567812", //18 "1234567812345678123", //19 "12345678123456781234567812345678", //32 "12345678123456781234567812345678123456781234567812345678123456", //62 "123456781234567812345678123456781234567812345678123456781234567", //63 "1234567812345678123456781234567812345678123456781234567812345678", //64 "12345678123456781234567812345678123456781234567812345678123456781", "123456781234567812345678123456781234567812345678123456781234567812", "1234567812345678123456781234567812345678123456781234567812345678123", "12345678123456781234567812345678123456781234567812345678123456781234", "123456781234567812345678123456781234567812345678123456781234567812345678", "12345678123456781234567812345678123456781234567812345678123456781234567812345678", "123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678", "12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678", "12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" "12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678", }; template inline int initString( const S2& str ) { S a( str ); return 0; } template inline int assignString( const S2& str ) { S a; a = str; return 0; } template inline int cmpEqString( const S& str1, const S& str2 ) { return str1 == str2; } template inline int cmpLessString( const S& str1, const S& str2 ) { return str1 < str2; } /* std::list listQString; int alocQString(char const * const pStr) { QString* a = new QString(pStr); listQString.push_back( a ); return 0; } int freeQString() { std::list::iterator it = listQString.begin(); std::list::iterator itEnd = listQString.end(); for ( ; it!=itEnd; ++it ) delete *it; listQString.clear(); return 0; } std::list listStdString; int alocStdString(char const * const pStr) { std::string* a = new std::string(pStr); listStdString.push_back( a ); return 0; } int freeStdString() { std::list::iterator it = listStdString.begin(); std::list::iterator itEnd = listStdString.end(); for ( ; it!=itEnd; ++it ) delete *it; listStdString.clear(); return 0; } */ template< class S1, class S2, int (*func1)( const S1& ), int (*func2)( const S2& ), int nProbes > void testStringsUnary( char const * const pStr ) { double dwStart, dwEnd; S1 s1_op( pStr ); S2 s2_op( pStr ); dwStart = getCurrentTime(); for ( int i = nProbes; i; --i ) volatile int a = func1(s1_op); dwEnd = getCurrentTime(); double dblDiff1 = dwEnd - dwStart; dwStart = getCurrentTime(); for ( int i = nProbes; i; --i ) volatile int a = func2(s2_op); dwEnd = getCurrentTime(); double dblDiff2 = dwEnd - dwStart; printf( "m1 %f m2 %f m1/m2 %f probs=%d\n", dblDiff1, dblDiff2, dblDiff1/dblDiff2, nProbes ); } template< class S1, class S2, int (*func1)(const S1&, const S1& ), int (*func2)(const S2&, const S2& ), int nProbes > void testStringsBinary( char const * const pStr1, char const * const pStr2 ) { double dwStart, dwEnd; S1 s1_op1( pStr1 ); S1 s1_op2( pStr2 ); S2 s2_op1( pStr1 ); S2 s2_op2( pStr2 ); dwStart = getCurrentTime(); for ( int i = nProbes; i; --i ) volatile int a = func1(s1_op1,s1_op2); dwEnd = getCurrentTime(); double dblDiff1 = dwEnd - dwStart; dwStart = getCurrentTime(); for ( int i = nProbes; i; --i ) volatile int a = func2(s2_op1,s2_op2); dwEnd = getCurrentTime(); double dblDiff2 = dwEnd - dwStart; printf( "m1 %f m2 %f m1/m2 %f probs=%d\n", dblDiff1, dblDiff2, dblDiff1/dblDiff2, nProbes ); } /* void testStrings( char const * const pStr ) { double dwStart, dwEnd; int nProbes = 5000000; dwStart = getCurrentTime(); for ( int i = nProbes; i; --i ) volatile int a = alocStdString(pStr); dwEnd = getCurrentTime(); printf( "alocStdString \t%f\t\t", dwEnd - dwStart ); dwStart = getCurrentTime(); { volatile int a = freeStdString(); } dwEnd = getCurrentTime(); printf( "freeStdString \t%f\n", dwEnd - dwStart ); dwStart = getCurrentTime(); for ( int i = nProbes; i; --i ) volatile int a = alocQString(pStr); dwEnd = getCurrentTime(); printf( "alocQString \t%f\t\t", dwEnd - dwStart ); dwStart = getCurrentTime(); { volatile int a = freeQString(); } dwEnd = getCurrentTime(); printf( "freeQString \t%f\n", dwEnd - dwStart ); dwStart = getCurrentTime(); for ( int i = nProbes; i; --i ) volatile int a = alocStdString(pStr); dwEnd = getCurrentTime(); printf( "alocStdString \t%f\t\t", dwEnd - dwStart ); dwStart = getCurrentTime(); { volatile int a = freeStdString(); } dwEnd = getCurrentTime(); printf( "freeStdString \t%f\n", dwEnd - dwStart ); dwStart = getCurrentTime(); for ( int i = nProbes; i; --i ) volatile int a = alocQString(pStr); dwEnd = getCurrentTime(); printf( "alocQString \t%f\t\t", dwEnd - dwStart ); dwStart = getCurrentTime(); { volatile int a = freeQString(); } dwEnd = getCurrentTime(); printf( "freeQString \t%f\n", dwEnd - dwStart ); } */ template void test() { #if 1 /* */ puts( "constructor(char*) \n" "============================================================"); for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]); ++i ) { printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); testStringsUnary, initString, 1000000>( testStr[i] ); } #endif #if 1 /* */ puts( "constructor(native) \n" "============================================================"); for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]); ++i ) { printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); testStringsUnary, initString, 1000000>( testStr[i] ); } #endif #if 1 /* */ puts( "operator = (char*) \n" "============================================================"); for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]); ++i ) { printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); testStringsUnary, assignString, 1000000>( testStr[i] ); } #endif #if 1 /* */ puts( "operator = (native) \n" "============================================================"); for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]); ++i ) { printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); testStringsUnary, assignString, 1000000>( testStr[i] ); } #endif #if 1 /* */ puts( "operator == () (equal strings)\n" "============================================================"); for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]) -1; ++i ) { printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); testStringsBinary< S1, S2, cmpEqString, cmpEqString, 1000000>( testStr[i], testStr[i] ); } #endif #if 1 /* */ puts( "operator == () (never equal strings)\n" "============================================================"); for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]) -1; ++i ) { printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); testStringsBinary< S1, S2, cmpEqString, cmpEqString, 1000000>( testStr[i], testStr[i+1] ); } #endif #if 1 /* */ puts( "operator < (less strings)\n" "============================================================"); for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]) -1; ++i ) { printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); testStringsBinary< S1, S2, cmpLessString, cmpLessString, 1000000>( testStr[i], testStr[i+1] ); } #endif #if 1 /* */ puts( "operator < () (great strings)\n" "============================================================"); for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]) -1; ++i ) { printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); testStringsBinary< S1, S2, cmpLessString, cmpLessString, 1000000>( testStr[i+1], testStr[i] ); } #endif } int main(int argc, char *argv[]) { // Init initGetCurrentTimeLib(); double dwStart, dwEnd; int nProbes; QCoreApplication a(argc, argv); #if 1 puts( "************************************************************\n" "************************************************************\n" "Testing m1=QString vs m2=std::string \n" "************************************************************"); test(); #endif #if 0 puts( "************************************************************\n" "************************************************************\n" "Testing m1=QString vs m2=fast_string \n" "************************************************************"); test(); #endif // return a.exec(); return 0; }