[prev in list] [next in list] [prev in thread] [next in thread]
List: koffice-devel
Subject: kword rendering speed: QTextFormatCollection
From: Jos van den Oever <Jos.van.den.Oever () kogmbh ! com>
Date: 2009-09-25 23:52:06
Message-ID: 200909260152.06879.Jos.van.den.Oever () kogmbh ! com
[Download RAW message or body]
Hi all,
I looked into KWord loading speed today and found an interesting bottleneck.
While loading the ODF 1.2 draft [1], 23% of CPU time was spent in
QTextFormatCollection::indexForFormat, which itself called
QTextFormat::operator==(QTextFormat const&) a lot.
The reason for this is inefficient looking up of QTextFormat indexes in
QTextFormatCollection. I have attached a patch for Qt that fixes the problem.
Unfortunately the patch is binary incompatible in the strictest sense. A
variable
QSet<uint> hashes;
is changed to
QMultiHash<uint,int> hashes;
Both types are 8 bytes and not used outside of QTextFormatCollection.
This patch speeds up rendering large documents.
I measured rendering by calling "time kword OpenDocument-v1.2-part1-cd03.odt"
and pressing the close button when i saw the white of the page. Here are the
rendering times in seconds:
without patch
9.14
11.19
10.44
8.08
8.22
10.93
------
9.67 +- 1.37
with patch
7.36
7.4
9.7
6.97
7.23
6.99
-----
7.61 +- 1.04
So an average improvement of 2 seconds. Not bad for a (long) performance day.
Cheers,
Jos
--
Jos van den Oever, software architect
+49 391 25 19 15 53
http://kogmbh.com/legal/
["qtextformatpatch" (text/x-patch)]
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index de6d10d..06ceb9c 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -257,13 +257,15 @@ private:
friend QDataStream &operator>>(QDataStream &, QTextFormat &);
};
+int hash(float d) { return *(int*)&d; }
+
static uint variantHash(const QVariant &variant)
{
switch (variant.type()) {
case QVariant::Invalid: return 0;
- case QVariant::Bool: return variant.toBool();
- case QVariant::Int: return variant.toInt();
- case QVariant::Double: return static_cast<int>(variant.toDouble());
+ case QVariant::Bool: return (QVariant::Bool << 4) + variant.toBool();
+ case QVariant::Int: return (QVariant::Int << 4) + variant.toInt();
+ case QVariant::Double: return hash(variant.toDouble());
case QVariant::String: return qHash(variant.toString());
case QVariant::Color: return qHash(qvariant_cast<QColor>(variant).rgb());
default: break;
@@ -2982,12 +2984,12 @@ QTextFormatCollection::~QTextFormatCollection()
int QTextFormatCollection::indexForFormat(const QTextFormat &format)
{
- uint hash = format.d ? format.d->hash() : 0;
+ uint hash = (format.d ? format.d->hash() : 0) + format.format_type;
if (hashes.contains(hash)) {
- for (int i = 0; i < formats.size(); ++i) {
- if (formats.at(i) == format)
- return i;
- }
+ foreach (int i, hashes.values(hash)) {
+ if (formats.count() > i && formats.at(i) == format)
+ return i;
+ }
}
int idx = formats.size();
formats.append(format);
@@ -2997,17 +3000,18 @@ int QTextFormatCollection::indexForFormat(const QTextFormat &format)
f.d = new QTextFormatPrivate;
f.d->resolveFont(defaultFnt);
- hashes.insert(hash);
+ hashes.insert(hash, idx);
return idx;
}
bool QTextFormatCollection::hasFormatCached(const QTextFormat &format) const
{
- uint hash = format.d ? format.d->hash() : 0;
+ uint hash = (format.d ? format.d->hash() : 0) + format.format_type;
if (hashes.contains(hash)) {
- for (int i = 0; i < formats.size(); ++i)
- if (formats.at(i) == format)
- return true;
+ foreach (int i, hashes.values(hash)) {
+ if (formats.count() > i && formats.at(i) == format)
+ return true;
+ }
}
return false;
}
diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h
index 40e73ab..1dcd47c 100644
--- a/src/gui/text/qtextformat_p.h
+++ b/src/gui/text/qtextformat_p.h
@@ -55,7 +55,7 @@
#include "QtGui/qtextformat.h"
#include "QtCore/qvector.h"
-#include "QtCore/qset.h"
+#include "QtCore/qhash.h"
QT_BEGIN_NAMESPACE
@@ -97,7 +97,7 @@ public:
FormatVector formats;
QVector<qint32> objFormats;
- QSet<uint> hashes;
+ QMultiHash<uint,int> hashes;
inline QFont defaultFont() const { return defaultFnt; }
void setDefaultFont(const QFont &f);
_______________________________________________
koffice-devel mailing list
koffice-devel@kde.org
https://mail.kde.org/mailman/listinfo/koffice-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic