KDE/kdelibs/kdecore/services
David Faure
faure at kde.org
Wed Sep 1 21:52:37 CEST 2010
SVN commit 1170673 by dfaure:
Who would have guessed that each call to QFile::size() caused an fstat? We'd better cache the file size to avoid
doing 500 stat calls in each call to KMimeTypeRepository::findFromContent (one per magic rule).
Found by JakubS who was using kpixmaptrace to collect backtraces for each fstat call.
$ strace -efstat kmimetypefinder -c sometextfile |& wc -l
before: 695
after: 80
CCMAIL: kde-optimize at kde.org
M +6 -7 kmimemagicrule.cpp
M +2 -2 kmimemagicrule_p.h
M +3 -2 kmimetyperepository.cpp
--- trunk/KDE/kdelibs/kdecore/services/kmimemagicrule.cpp #1170672:1170673
@@ -42,12 +42,12 @@
*
*/
-static bool testMatches(QIODevice* device, QByteArray& availableData, const QList<KMimeMagicMatch>& matches, const QString& mimeType)
+static bool testMatches(QIODevice* device, qint64 deviceSize, QByteArray& availableData, const QList<KMimeMagicMatch>& matches, const QString& mimeType)
{
for ( QList<KMimeMagicMatch>::const_iterator it = matches.begin(), end = matches.end() ;
it != end ; ++it ) {
const KMimeMagicMatch& match = *it;
- if (match.match(device, availableData, mimeType)) {
+ if (match.match(device, deviceSize, availableData, mimeType)) {
// One of the hierarchies matched -> mimetype recognized.
return true;
}
@@ -99,16 +99,15 @@
}
-bool KMimeMagicRule::match(QIODevice* device, QByteArray& availableData) const
+bool KMimeMagicRule::match(QIODevice* device, const qint64 deviceSize, QByteArray& availableData) const
{
- return testMatches(device, availableData, m_matches, m_mimetype);
+ return testMatches(device, deviceSize, availableData, m_matches, m_mimetype);
}
-bool KMimeMagicMatch::match(QIODevice* device, QByteArray& availableData, const QString& mimeType) const
+bool KMimeMagicMatch::match(QIODevice* device, const qint64 deviceSize, QByteArray& availableData, const QString& mimeType) const
{
// First, check that "this" matches, then we'll dive into subMatches if any.
- const qint64 deviceSize = device->size();
const qint64 mDataSize = m_data.size();
if (m_rangeStart + mDataSize > deviceSize)
return false; // file is too small
@@ -187,5 +186,5 @@
return true;
// Check that one of the submatches matches too
- return testMatches(device, availableData, m_subMatches, mimeType);
+ return testMatches(device, deviceSize, availableData, m_subMatches, mimeType);
}
--- trunk/KDE/kdelibs/kdecore/services/kmimemagicrule_p.h #1170672:1170673
@@ -30,7 +30,7 @@
*/
struct KMimeMagicMatch
{
- bool match(QIODevice* device, QByteArray& availableData, const QString& mimeType) const;
+ bool match(QIODevice* device, qint64 deviceSize, QByteArray& availableData, const QString& mimeType) const;
qint64 m_rangeStart;
qint64 m_rangeLength;
@@ -56,7 +56,7 @@
KMimeMagicRule(const QString& mimetype, int priority, const QList<KMimeMagicMatch>& matches)
: m_mimetype(mimetype), m_priority(priority), m_matches(matches) {}
- bool match(QIODevice* device, QByteArray& availableData) const;
+ bool match(QIODevice* device, qint64 deviceSize, QByteArray& availableData) const;
QString mimetype() const { return m_mimetype; }
int priority() const { return m_priority; }
--- trunk/KDE/kdelibs/kdecore/services/kmimetyperepository.cpp #1170672:1170673
@@ -221,7 +221,8 @@
KMimeType::Ptr KMimeTypeRepository::findFromContent(QIODevice* device, int* accuracy, QByteArray& beginning)
{
Q_ASSERT(device->isOpen());
- if (device->size() == 0) {
+ const qint64 deviceSize = device->size();
+ if (deviceSize == 0) {
if (accuracy)
*accuracy = 100;
return findMimeTypeByName("application/x-zerosize");
@@ -238,7 +239,7 @@
{
QReadLocker lock(&m_mutex);
Q_FOREACH ( const KMimeMagicRule& rule, m_magicRules ) {
- if (rule.match(device, beginning)) {
+ if (rule.match(device, deviceSize, beginning)) {
if (accuracy)
*accuracy = rule.priority();
return findMimeTypeByName(rule.mimetype());
More information about the Kde-optimize
mailing list