Kaydet (Commit) 787525a3 authored tarafından Noel Grandin's avatar Noel Grandin

tdf#125254 Performance: A spreadsheet opens too slow, NameSpaceEntry

NameSpaceEntry does not need to be a weak object, it is sufficient
to be ref-counted.

The empty string in SvXMLNamespaceMap can be statically allocated.

Don't allocate a NameSpaceEntry in GetKeyByAttrName_ if we don't
intend to cache it.

Takes the load time from 39.5s to 38.5s.

Change-Id: I4a9a1296af84c12d44e9b3ff354297f37d29f1e8
Reviewed-on: https://gerrit.libreoffice.org/72515
Tested-by: Jenkins
Reviewed-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
üst ecf456d0
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <sal/types.h> #include <sal/types.h>
#include <rtl/ustring.hxx> #include <rtl/ustring.hxx>
#include <rtl/ref.hxx> #include <rtl/ref.hxx>
#include <cppuhelper/weak.hxx> #include <salhelper/simplereferenceobject.hxx>
#include <limits.h> #include <limits.h>
...@@ -39,7 +39,7 @@ const sal_uInt16 XML_NAMESPACE_NONE = USHRT_MAX-1; ...@@ -39,7 +39,7 @@ const sal_uInt16 XML_NAMESPACE_NONE = USHRT_MAX-1;
const sal_uInt16 XML_NAMESPACE_UNKNOWN = USHRT_MAX; const sal_uInt16 XML_NAMESPACE_UNKNOWN = USHRT_MAX;
const sal_uInt16 XML_NAMESPACE_UNKNOWN_FLAG = 0x8000; const sal_uInt16 XML_NAMESPACE_UNKNOWN_FLAG = 0x8000;
class NameSpaceEntry : public cppu::OWeakObject class NameSpaceEntry : public salhelper::SimpleReferenceObject
{ {
public: public:
// sName refers to the full namespace name // sName refers to the full namespace name
...@@ -47,7 +47,7 @@ public: ...@@ -47,7 +47,7 @@ public:
// sPrefix is the prefix used to declare a given item to be from a given namespace // sPrefix is the prefix used to declare a given item to be from a given namespace
OUString sPrefix; OUString sPrefix;
// nKey is the unique identifier of a namespace // nKey is the unique identifier of a namespace
sal_uInt16 nKey; sal_uInt16 nKey;
}; };
typedef ::std::pair < sal_uInt16, OUString > QNamePair; typedef ::std::pair < sal_uInt16, OUString > QNamePair;
...@@ -65,12 +65,11 @@ struct QNamePairHash ...@@ -65,12 +65,11 @@ struct QNamePairHash
typedef std::unordered_map < QNamePair, OUString, QNamePairHash > QNameCache; typedef std::unordered_map < QNamePair, OUString, QNamePairHash > QNameCache;
typedef std::unordered_map < OUString, ::rtl::Reference <NameSpaceEntry > > NameSpaceHash; typedef std::unordered_map < OUString, ::rtl::Reference <NameSpaceEntry > > NameSpaceHash;
typedef std::map < sal_uInt16, ::rtl::Reference < NameSpaceEntry > > NameSpaceMap; typedef std::unordered_map < sal_uInt16, ::rtl::Reference < NameSpaceEntry > > NameSpaceMap;
class XMLOFF_DLLPUBLIC SvXMLNamespaceMap class XMLOFF_DLLPUBLIC SvXMLNamespaceMap
{ {
const OUString sXMLNS; OUString sXMLNS;
const OUString sEmpty;
NameSpaceHash aNameHash; NameSpaceHash aNameHash;
mutable NameSpaceHash aNameCache; mutable NameSpaceHash aNameCache;
......
...@@ -46,6 +46,8 @@ using namespace ::xmloff::token; ...@@ -46,6 +46,8 @@ using namespace ::xmloff::token;
* Martin 13/06/01 * Martin 13/06/01
*/ */
static const OUString sEmpty;
SvXMLNamespaceMap::SvXMLNamespaceMap() SvXMLNamespaceMap::SvXMLNamespaceMap()
: sXMLNS( GetXMLToken ( XML_XMLNS ) ) : sXMLNS( GetXMLToken ( XML_XMLNS ) )
{ {
...@@ -302,47 +304,50 @@ sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrName_( const OUString& rAttrName, ...@@ -302,47 +304,50 @@ sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrName_( const OUString& rAttrName,
} }
else else
{ {
rtl::Reference<NameSpaceEntry> xEntry(new NameSpaceEntry); OUString sEntryPrefix, sEntryName;
sal_Int32 nColonPos = rAttrName.indexOf( ':' ); sal_Int32 nColonPos = rAttrName.indexOf( ':' );
if( -1 == nColonPos ) if( -1 == nColonPos )
{ {
// case: no ':' found -> default namespace // case: no ':' found -> default namespace
xEntry->sPrefix.clear(); sEntryName = rAttrName;
xEntry->sName = rAttrName;
} }
else else
{ {
// normal case: ':' found -> get prefix/suffix // normal case: ':' found -> get prefix/suffix
xEntry->sPrefix = rAttrName.copy( 0L, nColonPos ); sEntryPrefix = rAttrName.copy( 0L, nColonPos );
xEntry->sName = rAttrName.copy( nColonPos + 1 ); sEntryName = rAttrName.copy( nColonPos + 1 );
} }
if( pPrefix ) if( pPrefix )
*pPrefix = xEntry->sPrefix; *pPrefix = sEntryPrefix;
if( pLocalName ) if( pLocalName )
*pLocalName = xEntry->sName; *pLocalName = sEntryName;
NameSpaceHash::const_iterator aIter = aNameHash.find( xEntry->sPrefix ); NameSpaceHash::const_iterator aIter = aNameHash.find( sEntryPrefix );
if ( aIter != aNameHash.end() ) if ( aIter != aNameHash.end() )
{ {
// found: retrieve namespace key // found: retrieve namespace key
nKey = xEntry->nKey = (*aIter).second->nKey; nKey = (*aIter).second->nKey;
if ( pNamespace ) if ( pNamespace )
*pNamespace = (*aIter).second->sName; *pNamespace = (*aIter).second->sName;
} }
else if ( xEntry->sPrefix == sXMLNS ) else if ( sEntryPrefix == sXMLNS )
// not found, but xmlns prefix: return xmlns 'namespace' // not found, but xmlns prefix: return xmlns 'namespace'
nKey = xEntry->nKey = XML_NAMESPACE_XMLNS; nKey = XML_NAMESPACE_XMLNS;
else if( nColonPos == -1 ) else if( nColonPos == -1 )
// not found, and no namespace: 'namespace' none // not found, and no namespace: 'namespace' none
nKey = xEntry->nKey = XML_NAMESPACE_NONE; nKey = XML_NAMESPACE_NONE;
else else
nKey = xEntry->nKey = XML_NAMESPACE_UNKNOWN; nKey = XML_NAMESPACE_UNKNOWN;
if (bCache) if (bCache)
{ {
aNameCache.emplace(rAttrName, xEntry); rtl::Reference<NameSpaceEntry> xEntry(new NameSpaceEntry);
xEntry->sPrefix = std::move(sEntryPrefix);
xEntry->sName = std::move(sEntryName);
xEntry->nKey = std::move(nKey);
aNameCache.emplace(rAttrName, std::move(xEntry));
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment