Files
test/cpp/std_vs_qt.cpp

726 lines
17 KiB
C++

#include <stdio.h>
#include "getCurrentTime.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QString>
#include <list>
#include <memory>
#include <string>
#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 T, int N>
class fast_allocator
#ifndef USE_MALLOC
: public std::allocator<T>
#endif
{
char memory[N];
#ifndef ALLOC_AT_ONCE
char* marker;
#endif
public:
typedef std::allocator<T> 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<class _Other>
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<T,N>& ) throw()
#ifndef ALLOC_AT_ONCE
: marker( memory )
#endif
{}
// construct from a related allocator (do nothing)
// template<class _Other>
// 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<pointer>(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<pointer>(memory)
|| static_cast<pointer>(&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<pointer>(memory);
#else
if ( sizeof(T)*nCount < (&memory[N] - marker) )
{
pointer p = static_cast<pointer>(marker);
marker += s;
return p;
}
#endif
else
#ifdef USE_MALLOC
return static_cast<char*>(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 <class T, int N>
inline
bool operator== ( const fast_allocator<T,N>& op1,
const fast_allocator<T,N>& op2 )
{
return &op1 == &op2;
}
// STRUCT char_traits<char> (FROM <string>)
template<class C>
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<char_type*>(::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<char_type*>(::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<CharType>,
class Allocator=fast_allocator<CharType,64>
>
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 <class Elem, class Traits, class Alloc>
inline
bool operator==(
const fast_basic_string<Elem, Traits, Alloc>& l,
const fast_basic_string<Elem, Traits, Alloc>& 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 <class S, class S2>
inline
int initString( const S2& str )
{
S a( str );
return 0;
}
template <class S, class S2>
inline
int assignString( const S2& str )
{
S a;
a = str;
return 0;
}
template <class S>
inline
int cmpEqString( const S& str1, const S& str2 )
{
return str1 == str2;
}
template <class S>
inline
int cmpLessString( const S& str1, const S& str2 )
{
return str1 < str2;
}
/*
std::list<QString*> listQString;
int alocQString(char const * const pStr)
{
QString* a = new QString(pStr);
listQString.push_back( a );
return 0;
}
int freeQString()
{
std::list<QString*>::iterator it = listQString.begin();
std::list<QString*>::iterator itEnd = listQString.end();
for ( ; it!=itEnd; ++it )
delete *it;
listQString.clear();
return 0;
}
std::list<std::string*> listStdString;
int alocStdString(char const * const pStr)
{
std::string* a = new std::string(pStr);
listStdString.push_back( a );
return 0;
}
int freeStdString()
{
std::list<std::string*>::iterator it = listStdString.begin();
std::list<std::string*>::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 <class S1, class S2>
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<char const * const,
char const * const,
initString<S1, char const * const>,
initString<S2, char const * const>,
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<S1,
S2,
initString<S1, S1>,
initString<S2, S2>,
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<char const * const,
char const * const,
assignString<S1, char const * const>,
assignString<S2, char const * const>,
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<S1,
S2,
assignString<S1, S1>,
assignString<S2, S2>,
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<S1>,
cmpEqString<S2>,
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<S1>,
cmpEqString<S2>,
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<S1>,
cmpLessString<S2>,
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<S1>,
cmpLessString<S2>,
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<QString,std::string>();
#endif
#if 0
puts( "************************************************************\n"
"************************************************************\n"
"Testing m1=QString vs m2=fast_string \n"
"************************************************************");
test<QString,fast_string>();
#endif
// return a.exec();
return 0;
}