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