2008-07-26 19:07:05 -04:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: tests/benchmarks/strings.cpp
|
|
|
|
// Purpose: String-related benchmarks
|
|
|
|
// Author: Vadim Zeitlin
|
|
|
|
// Created: 2008-07-19
|
|
|
|
// RCS-ID: $Id$
|
|
|
|
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
|
|
|
|
// Licence: wxWindows license
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "wx/string.h"
|
2008-08-13 11:48:09 -04:00
|
|
|
#include "wx/ffile.h"
|
2008-07-26 19:07:05 -04:00
|
|
|
|
|
|
|
#include "bench.h"
|
2008-08-13 11:48:09 -04:00
|
|
|
#include "htmlparser/htmlpars.h"
|
2008-07-26 19:07:05 -04:00
|
|
|
|
|
|
|
static const char asciistr[] =
|
|
|
|
"This is just the first line of a very long 7 bit ASCII string"
|
|
|
|
"This is just the second line of a very long 7 bit ASCII string"
|
|
|
|
"This is just the third line of a very long 7 bit ASCII string"
|
|
|
|
"This is just the fourth line of a very long 7 bit ASCII string"
|
|
|
|
"This is just the fifth line of a very long 7 bit ASCII string"
|
|
|
|
"This is just the sixth line of a very long 7 bit ASCII string"
|
|
|
|
"This is just the seventh line of a very long 7 bit ASCII string"
|
|
|
|
"This is just the eighth line of a very long 7 bit ASCII string"
|
|
|
|
"This is just the ninth line of a very long 7 bit ASCII string"
|
|
|
|
"This is just the tenth line of a very long 7 bit ASCII string"
|
|
|
|
;
|
|
|
|
|
|
|
|
static const char utf8str[] =
|
|
|
|
"\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 0"
|
|
|
|
"\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 1"
|
|
|
|
"\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 2"
|
|
|
|
"\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 3"
|
|
|
|
"\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 4"
|
|
|
|
"\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 5"
|
|
|
|
"\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 6"
|
|
|
|
"\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 7"
|
|
|
|
"\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 8"
|
|
|
|
"\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 9"
|
|
|
|
;
|
|
|
|
|
2008-08-29 09:56:03 -04:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
const wxString& GetTestAsciiString()
|
|
|
|
{
|
|
|
|
static wxString testString;
|
|
|
|
if ( testString.empty() )
|
|
|
|
{
|
2008-10-13 18:25:51 -04:00
|
|
|
long num = Bench::GetNumericParameter();
|
|
|
|
if ( !num )
|
|
|
|
num = 1;
|
|
|
|
|
|
|
|
for ( long n = 0; n < num; n++ )
|
2008-08-29 09:56:03 -04:00
|
|
|
testString += wxString::FromAscii(asciistr);
|
|
|
|
}
|
|
|
|
|
|
|
|
return testString;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
2008-07-26 19:07:05 -04:00
|
|
|
// this is just a baseline
|
|
|
|
BENCHMARK_FUNC(Strlen)
|
|
|
|
{
|
|
|
|
if ( strlen(utf8str) != WXSIZEOF(utf8str) - 1 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if ( strlen(asciistr) != WXSIZEOF(asciistr) - 1 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// FromUTF8() benchmarks
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(FromUTF8)
|
|
|
|
{
|
|
|
|
wxString s = wxString::FromUTF8(utf8str);
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
s = wxString::FromUTF8(asciistr);
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(FromUTF8WithNpos)
|
|
|
|
{
|
|
|
|
wxString s = wxString::FromUTF8(utf8str, wxString::npos);
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
s = wxString::FromUTF8(asciistr, wxString::npos);
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(FromUTF8WithLen)
|
|
|
|
{
|
|
|
|
wxString s = wxString::FromUTF8(utf8str, WXSIZEOF(utf8str));
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
s = wxString::FromUTF8(asciistr, WXSIZEOF(asciistr));
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// FromUTF8Unchecked() benchmarks
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(FromUTF8Unchecked)
|
|
|
|
{
|
|
|
|
wxString s = wxString::FromUTF8Unchecked(utf8str);
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
s = wxString::FromUTF8Unchecked(asciistr);
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(FromUTF8UncheckedWithNpos)
|
|
|
|
{
|
|
|
|
wxString s = wxString::FromUTF8Unchecked(utf8str, wxString::npos);
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
s = wxString::FromUTF8Unchecked(asciistr, wxString::npos);
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(FromUTF8UncheckedWithLen)
|
|
|
|
{
|
|
|
|
wxString s = wxString::FromUTF8Unchecked(utf8str, WXSIZEOF(utf8str));
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
s = wxString::FromUTF8Unchecked(asciistr, WXSIZEOF(asciistr));
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// FromAscii() benchmarks
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(FromAscii)
|
|
|
|
{
|
|
|
|
wxString s = wxString::FromAscii(asciistr);
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(FromAsciiWithNpos)
|
|
|
|
{
|
|
|
|
wxString s = wxString::FromAscii(asciistr);
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(FromAsciiWithLen)
|
|
|
|
{
|
|
|
|
wxString s = wxString::FromAscii(asciistr, WXSIZEOF(asciistr));
|
|
|
|
if ( s.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// simple string iteration
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// baseline
|
|
|
|
BENCHMARK_FUNC(ForCString)
|
|
|
|
{
|
|
|
|
for ( size_t n = 0; n < WXSIZEOF(asciistr); n++ )
|
|
|
|
{
|
|
|
|
if ( asciistr[n] == '~' )
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(ForStringIndex)
|
|
|
|
{
|
2008-08-29 09:56:03 -04:00
|
|
|
const wxString& s = GetTestAsciiString();
|
2008-07-26 19:07:05 -04:00
|
|
|
const size_t len = s.length();
|
|
|
|
for ( size_t n = 0; n < len; n++ )
|
|
|
|
{
|
|
|
|
if ( s[n] == '~' )
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(ForStringIter)
|
|
|
|
{
|
2008-08-29 09:56:03 -04:00
|
|
|
const wxString& s = GetTestAsciiString();
|
2008-07-26 19:07:05 -04:00
|
|
|
const wxString::const_iterator end = s.end();
|
|
|
|
for ( wxString::const_iterator i = s.begin(); i != end; ++i )
|
|
|
|
{
|
|
|
|
if ( *i == '~' )
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(ForStringRIter)
|
|
|
|
{
|
2008-08-29 09:56:03 -04:00
|
|
|
const wxString& s = GetTestAsciiString();
|
2008-07-26 19:07:05 -04:00
|
|
|
const wxString::const_reverse_iterator rend = s.rend();
|
|
|
|
for ( wxString::const_reverse_iterator i = s.rbegin(); i != rend; ++i )
|
|
|
|
{
|
|
|
|
if ( *i == '~' )
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2008-07-30 09:56:17 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// wxString::Replace()
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2008-08-11 15:31:23 -04:00
|
|
|
const size_t ASCIISTR_LEN = strlen(asciistr);
|
2008-07-30 09:56:17 -04:00
|
|
|
|
|
|
|
BENCHMARK_FUNC(ReplaceLoop)
|
|
|
|
{
|
2008-08-11 15:31:23 -04:00
|
|
|
wxString str('x', ASCIISTR_LEN);
|
|
|
|
for ( size_t n = 0; n < ASCIISTR_LEN; n++ )
|
2008-07-30 09:56:17 -04:00
|
|
|
{
|
|
|
|
if ( str[n] == 'a' )
|
|
|
|
str[n] = 'z';
|
|
|
|
}
|
|
|
|
|
|
|
|
return str.length() != 0;
|
|
|
|
}
|
|
|
|
|
2008-07-30 11:25:19 -04:00
|
|
|
BENCHMARK_FUNC(ReplaceNone)
|
2008-07-30 09:56:17 -04:00
|
|
|
{
|
2008-08-11 15:31:23 -04:00
|
|
|
wxString str('x', ASCIISTR_LEN);
|
2008-07-30 11:25:19 -04:00
|
|
|
return str.Replace("a", "z") == 0;
|
|
|
|
}
|
2008-07-30 09:56:17 -04:00
|
|
|
|
2008-07-30 11:25:19 -04:00
|
|
|
BENCHMARK_FUNC(ReplaceSome)
|
|
|
|
{
|
|
|
|
wxString str(asciistr);
|
|
|
|
return str.Replace("7", "8") != 0;
|
2008-07-30 09:56:17 -04:00
|
|
|
}
|
|
|
|
|
2008-07-30 11:25:19 -04:00
|
|
|
BENCHMARK_FUNC(ReplaceAll)
|
2008-07-30 09:56:17 -04:00
|
|
|
{
|
2008-08-11 15:31:23 -04:00
|
|
|
wxString str('x', ASCIISTR_LEN);
|
2008-07-30 11:25:19 -04:00
|
|
|
return str.Replace("x", "y") != 0;
|
2008-07-30 09:56:17 -04:00
|
|
|
}
|
|
|
|
|
2009-03-07 11:07:58 -05:00
|
|
|
BENCHMARK_FUNC(ReplaceLonger)
|
|
|
|
{
|
|
|
|
wxString str('x', ASCIISTR_LEN);
|
|
|
|
return str.Replace("x", "yy") != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(ReplaceShorter)
|
|
|
|
{
|
|
|
|
wxString str('x', ASCIISTR_LEN);
|
|
|
|
return str.Replace("xx", "y") != 0;
|
|
|
|
}
|
|
|
|
|
2008-08-11 15:31:23 -04:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// string buffers: wx[W]CharBuffer
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(CharBuffer)
|
|
|
|
{
|
|
|
|
wxString str(asciistr);
|
|
|
|
|
|
|
|
// NB: wxStrlen() is here to simulate some use of the returned buffer.
|
|
|
|
// Both mb_str() and wc_str() are used so that this code does something
|
|
|
|
// nontrivial in any build.
|
|
|
|
return wxStrlen(str.mb_str()) == ASCIISTR_LEN &&
|
|
|
|
wxStrlen(str.wc_str()) == ASCIISTR_LEN;
|
|
|
|
}
|
2008-08-13 11:48:09 -04:00
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// wxString::operator[] - parse large HTML page
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class DummyParser : public wx28HtmlParser
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual wxObject* GetProduct() { return NULL; }
|
|
|
|
virtual void AddText(const wxChar*) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
BENCHMARK_FUNC(ParseHTML)
|
|
|
|
{
|
|
|
|
// static so that construction time is not counted
|
|
|
|
static DummyParser parser;
|
|
|
|
static wxString html;
|
|
|
|
if ( html.empty() )
|
|
|
|
{
|
2008-08-28 13:14:39 -04:00
|
|
|
wxString html1;
|
|
|
|
wxFFile("htmltest.html").ReadAll(&html1, wxConvUTF8);
|
|
|
|
|
|
|
|
// this is going to make for some invalid HTML, of course, but it
|
|
|
|
// doesn't really matter
|
2008-10-13 18:25:51 -04:00
|
|
|
long num = Bench::GetNumericParameter();
|
|
|
|
if ( !num )
|
|
|
|
num = 1;
|
|
|
|
|
|
|
|
for ( long n = 0; n < num; n++ )
|
2008-08-28 13:14:39 -04:00
|
|
|
html += html1;
|
2008-08-13 11:48:09 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
parser.Parse(html);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|