diff --git a/tests/benchmarks/Makefile.in b/tests/benchmarks/Makefile.in
index 92058a3b53..321eee4790 100644
--- a/tests/benchmarks/Makefile.in
+++ b/tests/benchmarks/Makefile.in
@@ -44,6 +44,8 @@ BENCH_CXXFLAGS = -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
$(CXXFLAGS)
BENCH_OBJECTS = \
bench_bench.o \
+ bench_htmlpars.o \
+ bench_htmltag.o \
bench_strings.o \
bench_tls.o
@@ -84,7 +86,7 @@ COND_WXUSE_REGEX_BUILTIN___LIB_REGEX_p = \
### Targets: ###
-all: bench$(EXEEXT)
+all: bench$(EXEEXT) data
install: all
@@ -106,9 +108,27 @@ bench$(EXEEXT): $(BENCH_OBJECTS)
$(__bench___mac_setfilecmd)
$(SAMPLES_RPATH_POSTLINK)
+data:
+ @mkdir -p .
+ @for f in htmltest.html; do \
+ if test ! -f ./$$f -a ! -d ./$$f ; \
+ then x=yep ; \
+ else x=`find $(srcdir)/$$f -newer ./$$f -print` ; \
+ fi; \
+ case "$$x" in ?*) \
+ cp -pRf $(srcdir)/$$f . ;; \
+ esac; \
+ done
+
bench_bench.o: $(srcdir)/bench.cpp
$(CXXC) -c -o $@ $(BENCH_CXXFLAGS) $(srcdir)/bench.cpp
+bench_htmlpars.o: $(srcdir)/htmlparser/htmlpars.cpp
+ $(CXXC) -c -o $@ $(BENCH_CXXFLAGS) $(srcdir)/htmlparser/htmlpars.cpp
+
+bench_htmltag.o: $(srcdir)/htmlparser/htmltag.cpp
+ $(CXXC) -c -o $@ $(BENCH_CXXFLAGS) $(srcdir)/htmlparser/htmltag.cpp
+
bench_strings.o: $(srcdir)/strings.cpp
$(CXXC) -c -o $@ $(BENCH_CXXFLAGS) $(srcdir)/strings.cpp
@@ -128,4 +148,4 @@ $(srcdir)/include/wx/stc/stc.h
# Include dependency info, if present:
@IF_GNU_MAKE@-include .deps/*.d
-.PHONY: all install uninstall clean distclean
+.PHONY: all install uninstall clean distclean data
diff --git a/tests/benchmarks/bench.bkl b/tests/benchmarks/bench.bkl
index d8016412aa..f69564c839 100644
--- a/tests/benchmarks/bench.bkl
+++ b/tests/benchmarks/bench.bkl
@@ -11,12 +11,18 @@
template_append="wx_append_base">
bench.cpp
+ htmlparser/htmlpars.cpp
+ htmlparser/htmltag.cpp
strings.cpp
tls.cpp
base
+
+ htmltest.html
+
+
+ ProjectGUID="{205F8D16-BA71-560B-A3DF-7A2A93B16CF6}">
+ Name="Win32"/>
-
-
-
+ CharacterSet="1">
+ Name="VCPreBuildEventTool"/>
+ Name="VCCustomBuildTool"/>
+ Name="VCXMLDataGeneratorTool"/>
+ Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCIDLTool"/>
+ SuppressStartupBanner="true"/>
+ Name="VCManagedResourceCompilerTool"/>
+ AdditionalIncludeDirectories=".\..\..\lib\vc7_dll\mswunivu;.\..\..\include;."
+ PreprocessorDefinitions="__WXMSW__;__WXUNIVERSAL__;_UNICODE;WXUSINGDLL;_CONSOLE;wxUSE_GUI=0"/>
+ Name="VCPreLinkEventTool"/>
+ ProgramDatabaseFile="vc7_mswunivudll\bench.pdb"
+ TargetMachine="1"/>
+ Name="VCALinkTool"/>
+ Name="VCXDCMakeTool"/>
+ OutputFile="vc7_mswunivudll\bench.bsc"
+ SuppressStartupBanner="true"/>
+ Name="VCFxCopTool"/>
+ Name="VCAppVerifierTool"/>
+ Name="VCWebDeploymentTool"/>
+ Name="VCPostBuildEventTool"/>
+ CharacterSet="1">
+ Name="VCPreBuildEventTool"/>
+ Name="VCCustomBuildTool"/>
+ Name="VCXMLDataGeneratorTool"/>
+ Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCIDLTool"/>
+ SuppressStartupBanner="true"/>
+ Name="VCManagedResourceCompilerTool"/>
+ AdditionalIncludeDirectories=".\..\..\lib\vc7_dll\mswunivud;.\..\..\include;."
+ PreprocessorDefinitions="_DEBUG;__WXMSW__;__WXUNIVERSAL__;__WXDEBUG__;_UNICODE;WXUSINGDLL;_CONSOLE;wxUSE_GUI=0"/>
+ Name="VCPreLinkEventTool"/>
+ ProgramDatabaseFile="vc7_mswunivuddll\bench.pdb"
+ TargetMachine="1"/>
+ Name="VCALinkTool"/>
+ Name="VCXDCMakeTool"/>
+ OutputFile="vc7_mswunivuddll\bench.bsc"
+ SuppressStartupBanner="true"/>
+ Name="VCFxCopTool"/>
+ Name="VCAppVerifierTool"/>
+ Name="VCWebDeploymentTool"/>
+ Name="VCPostBuildEventTool"/>
+ CharacterSet="1">
+ Name="VCPreBuildEventTool"/>
+ Name="VCCustomBuildTool"/>
+ Name="VCXMLDataGeneratorTool"/>
+ Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCIDLTool"/>
+ SuppressStartupBanner="true"/>
+ Name="VCManagedResourceCompilerTool"/>
+ AdditionalIncludeDirectories=".\..\..\lib\vc7_dll\mswu;.\..\..\include;."
+ PreprocessorDefinitions="__WXMSW__;_UNICODE;WXUSINGDLL;_CONSOLE;wxUSE_GUI=0"/>
+ Name="VCPreLinkEventTool"/>
+ ProgramDatabaseFile="vc7_mswudll\bench.pdb"
+ TargetMachine="1"/>
+ Name="VCALinkTool"/>
+ Name="VCXDCMakeTool"/>
+ OutputFile="vc7_mswudll\bench.bsc"
+ SuppressStartupBanner="true"/>
+ Name="VCFxCopTool"/>
+ Name="VCAppVerifierTool"/>
+ Name="VCWebDeploymentTool"/>
+ Name="VCPostBuildEventTool"/>
+ CharacterSet="1">
+ Name="VCPreBuildEventTool"/>
+ Name="VCCustomBuildTool"/>
+ Name="VCXMLDataGeneratorTool"/>
+ Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCIDLTool"/>
+ SuppressStartupBanner="true"/>
+ Name="VCManagedResourceCompilerTool"/>
+ AdditionalIncludeDirectories=".\..\..\lib\vc7_dll\mswud;.\..\..\include;."
+ PreprocessorDefinitions="_DEBUG;__WXMSW__;__WXDEBUG__;_UNICODE;WXUSINGDLL;_CONSOLE;wxUSE_GUI=0"/>
+ Name="VCPreLinkEventTool"/>
+ ProgramDatabaseFile="vc7_mswuddll\bench.pdb"
+ TargetMachine="1"/>
+ Name="VCALinkTool"/>
+ Name="VCXDCMakeTool"/>
+ OutputFile="vc7_mswuddll\bench.bsc"
+ SuppressStartupBanner="true"/>
+ Name="VCFxCopTool"/>
+ Name="VCAppVerifierTool"/>
+ Name="VCWebDeploymentTool"/>
+ Name="VCPostBuildEventTool"/>
+ CharacterSet="1">
+ Name="VCPreBuildEventTool"/>
+ Name="VCCustomBuildTool"/>
+ Name="VCXMLDataGeneratorTool"/>
+ Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCIDLTool"/>
+ SuppressStartupBanner="true"/>
+ Name="VCManagedResourceCompilerTool"/>
+ AdditionalIncludeDirectories=".\..\..\lib\vc7_lib\mswunivu;.\..\..\include;."
+ PreprocessorDefinitions="__WXMSW__;__WXUNIVERSAL__;_UNICODE;_CONSOLE;wxUSE_GUI=0"/>
+ Name="VCPreLinkEventTool"/>
+ ProgramDatabaseFile="vc7_mswunivu\bench.pdb"
+ TargetMachine="1"/>
+ Name="VCALinkTool"/>
+ Name="VCXDCMakeTool"/>
+ OutputFile="vc7_mswunivu\bench.bsc"
+ SuppressStartupBanner="true"/>
+ Name="VCFxCopTool"/>
+ Name="VCAppVerifierTool"/>
+ Name="VCWebDeploymentTool"/>
+ Name="VCPostBuildEventTool"/>
+ CharacterSet="1">
+ Name="VCPreBuildEventTool"/>
+ Name="VCCustomBuildTool"/>
+ Name="VCXMLDataGeneratorTool"/>
+ Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCIDLTool"/>
+ SuppressStartupBanner="true"/>
+ Name="VCManagedResourceCompilerTool"/>
+ AdditionalIncludeDirectories=".\..\..\lib\vc7_lib\mswunivud;.\..\..\include;."
+ PreprocessorDefinitions="_DEBUG;__WXMSW__;__WXUNIVERSAL__;__WXDEBUG__;_UNICODE;_CONSOLE;wxUSE_GUI=0"/>
+ Name="VCPreLinkEventTool"/>
+ ProgramDatabaseFile="vc7_mswunivud\bench.pdb"
+ TargetMachine="1"/>
+ Name="VCALinkTool"/>
+ Name="VCXDCMakeTool"/>
+ OutputFile="vc7_mswunivud\bench.bsc"
+ SuppressStartupBanner="true"/>
+ Name="VCFxCopTool"/>
+ Name="VCAppVerifierTool"/>
+ Name="VCWebDeploymentTool"/>
+ Name="VCPostBuildEventTool"/>
+ CharacterSet="1">
+ Name="VCPreBuildEventTool"/>
+ Name="VCCustomBuildTool"/>
+ Name="VCXMLDataGeneratorTool"/>
+ Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCIDLTool"/>
+ SuppressStartupBanner="true"/>
+ Name="VCManagedResourceCompilerTool"/>
+ AdditionalIncludeDirectories=".\..\..\lib\vc7_lib\mswu;.\..\..\include;."
+ PreprocessorDefinitions="__WXMSW__;_UNICODE;_CONSOLE;wxUSE_GUI=0"/>
+ Name="VCPreLinkEventTool"/>
+ ProgramDatabaseFile="vc7_mswu\bench.pdb"
+ TargetMachine="1"/>
+ Name="VCALinkTool"/>
+ Name="VCXDCMakeTool"/>
+ OutputFile="vc7_mswu\bench.bsc"
+ SuppressStartupBanner="true"/>
+ Name="VCFxCopTool"/>
+ Name="VCAppVerifierTool"/>
+ Name="VCWebDeploymentTool"/>
+ Name="VCPostBuildEventTool"/>
+ CharacterSet="1">
+ Name="VCPreBuildEventTool"/>
+ Name="VCCustomBuildTool"/>
+ Name="VCXMLDataGeneratorTool"/>
+ Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCIDLTool"/>
+ SuppressStartupBanner="true"/>
+ Name="VCManagedResourceCompilerTool"/>
+ AdditionalIncludeDirectories=".\..\..\lib\vc7_lib\mswud;.\..\..\include;."
+ PreprocessorDefinitions="_DEBUG;__WXMSW__;__WXDEBUG__;_UNICODE;_CONSOLE;wxUSE_GUI=0"/>
+ Name="VCPreLinkEventTool"/>
+ ProgramDatabaseFile="vc7_mswud\bench.pdb"
+ TargetMachine="1"/>
+ Name="VCALinkTool"/>
+ Name="VCXDCMakeTool"/>
+ OutputFile="vc7_mswud\bench.bsc"
+ SuppressStartupBanner="true"/>
+ Name="VCFxCopTool"/>
+ Name="VCAppVerifierTool"/>
+ Name="VCWebDeploymentTool"/>
+ Name="VCPostBuildEventTool"/>
@@ -781,17 +624,17 @@
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx">
+ RelativePath=".\bench.cpp"/>
+ RelativePath=".\htmlparser\htmlpars.cpp"/>
+ RelativePath=".\htmlparser\htmltag.cpp"/>
+
+
diff --git a/tests/benchmarks/htmlparser/README b/tests/benchmarks/htmlparser/README
new file mode 100644
index 0000000000..37e3b969d3
--- /dev/null
+++ b/tests/benchmarks/htmlparser/README
@@ -0,0 +1,4 @@
+
+This is a copy of wxWidgets 2.8's wxHTML parser. Unlike the 2.9+ version, it
+uses wxString::operator[] during parsing and so is perfect for testing
+real-life perfomance of the new wxString class' operator[] caching.
diff --git a/tests/benchmarks/htmlparser/htmlpars.cpp b/tests/benchmarks/htmlparser/htmlpars.cpp
new file mode 100644
index 0000000000..541fb80650
--- /dev/null
+++ b/tests/benchmarks/htmlparser/htmlpars.cpp
@@ -0,0 +1,954 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: src/html/htmlpars.cpp
+// Purpose: wx28HtmlParser class (generic parser)
+// Author: Vaclav Slavik
+// RCS-ID: $Id$
+// Copyright: (c) 1999 Vaclav Slavik
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#include "htmlpars.h"
+
+#ifndef WXPRECOMP
+ #include "wx/dynarray.h"
+ #include "wx/log.h"
+ #include "wx/intl.h"
+ #include "wx/app.h"
+#endif
+
+#include "wx/tokenzr.h"
+#include "wx/wfstream.h"
+#include "wx/url.h"
+#include "wx/fontmap.h"
+#include "wx/html/htmldefs.h"
+#include "wx/arrimpl.cpp"
+
+#ifdef __WXWINCE__
+ #include "wx/msw/wince/missing.h" // for bsearch()
+#endif
+
+// DLL options compatibility check:
+WX_CHECK_BUILD_OPTIONS("wxHTML")
+
+const wxChar *wxTRACE_HTML_DEBUG = _T("htmldebug");
+
+//-----------------------------------------------------------------------------
+// wx28HtmlParser helpers
+//-----------------------------------------------------------------------------
+
+class wx28HtmlTextPiece
+{
+public:
+ wx28HtmlTextPiece(int pos, int lng) : m_pos(pos), m_lng(lng) {}
+ int m_pos, m_lng;
+};
+
+WX_DECLARE_OBJARRAY(wx28HtmlTextPiece, wx28HtmlTextPieces);
+WX_DEFINE_OBJARRAY(wx28HtmlTextPieces)
+
+class wx28HtmlParserState
+{
+public:
+ wx28HtmlTag *m_curTag;
+ wx28HtmlTag *m_tags;
+ wx28HtmlTextPieces *m_textPieces;
+ int m_curTextPiece;
+ wxString m_source;
+ wx28HtmlParserState *m_nextState;
+};
+
+//-----------------------------------------------------------------------------
+// wx28HtmlParser
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_ABSTRACT_CLASS(wx28HtmlParser,wxObject)
+
+wx28HtmlParser::wx28HtmlParser()
+ : wxObject(), m_HandlersHash(wxKEY_STRING),
+ m_FS(NULL), m_HandlersStack(NULL)
+{
+ m_entitiesParser = new wx28HtmlEntitiesParser;
+ m_Tags = NULL;
+ m_CurTag = NULL;
+ m_TextPieces = NULL;
+ m_CurTextPiece = 0;
+ m_SavedStates = NULL;
+}
+
+wx28HtmlParser::~wx28HtmlParser()
+{
+ while (RestoreState()) {}
+ DestroyDOMTree();
+
+ if (m_HandlersStack)
+ {
+ wxList& tmp = *m_HandlersStack;
+ wxList::iterator it, en;
+ for( it = tmp.begin(), en = tmp.end(); it != en; ++it )
+ delete (wxHashTable*)*it;
+ tmp.clear();
+ }
+ delete m_HandlersStack;
+ m_HandlersHash.Clear();
+ WX_CLEAR_LIST(wxList, m_HandlersList);
+ delete m_entitiesParser;
+}
+
+wxObject* wx28HtmlParser::Parse(const wxString& source)
+{
+ InitParser(source);
+ DoParsing();
+ wxObject *result = GetProduct();
+ DoneParser();
+ return result;
+}
+
+void wx28HtmlParser::InitParser(const wxString& source)
+{
+ SetSource(source);
+ m_stopParsing = false;
+}
+
+void wx28HtmlParser::DoneParser()
+{
+ DestroyDOMTree();
+}
+
+void wx28HtmlParser::SetSource(const wxString& src)
+{
+ DestroyDOMTree();
+ m_Source = src;
+ CreateDOMTree();
+ m_CurTag = NULL;
+ m_CurTextPiece = 0;
+}
+
+void wx28HtmlParser::CreateDOMTree()
+{
+ wx28HtmlTagsCache cache(m_Source);
+ m_TextPieces = new wx28HtmlTextPieces;
+ CreateDOMSubTree(NULL, 0, m_Source.length(), &cache);
+ m_CurTextPiece = 0;
+}
+
+extern bool wxIsCDATAElement(const wxChar *tag);
+
+void wx28HtmlParser::CreateDOMSubTree(wx28HtmlTag *cur,
+ int begin_pos, int end_pos,
+ wx28HtmlTagsCache *cache)
+{
+ if (end_pos <= begin_pos) return;
+
+ wxChar c;
+ int i = begin_pos;
+ int textBeginning = begin_pos;
+
+ // If the tag contains CDATA text, we include the text between beginning
+ // and ending tag verbosely. Setting i=end_pos will skip to the very
+ // end of this function where text piece is added, bypassing any child
+ // tags parsing (CDATA element can't have child elements by definition):
+ if (cur != NULL && wxIsCDATAElement(cur->GetName().c_str()))
+ {
+ i = end_pos;
+ }
+
+ while (i < end_pos)
+ {
+ c = m_Source.GetChar(i);
+
+ if (c == wxT('<'))
+ {
+ // add text to m_TextPieces:
+ if (i - textBeginning > 0)
+ m_TextPieces->Add(
+ wx28HtmlTextPiece(textBeginning, i - textBeginning));
+
+ // if it is a comment, skip it:
+ if (i < end_pos-6 && m_Source.GetChar(i+1) == wxT('!') &&
+ m_Source.GetChar(i+2) == wxT('-') &&
+ m_Source.GetChar(i+3) == wxT('-'))
+ {
+ // Comments begin with "