[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-optimize
Subject:    option to disable kbuildsycoca check during kdeinit startup
From:       Lubos Lunak <l.lunak () suse ! cz>
Date:       2004-09-23 16:54:44
Message-ID: 200409231854.44347.l.lunak () suse ! cz
[Download RAW message or body]

Hello,

 the attached patch adds an option to disable scanning of most of the 
directories containing .desktop files, i.e. kbuildsycoca only checks ksycoca 
is actually usable, and kded doesn't set up KDirWatcher. This avoids reading 
all those directories during KDE or kdeinit startup.

 I created the patch because some asked for this at the SUSE Labs conference 
while discussing various things related to performance. Their reason for this 
was mostly starting KDE apps outside of KDE, when kdeinit needs to be run 
first. Since all those directories containing .desktop files are usually not 
in caches, scanning them takes some time.

 The question, however, is if this would be actually worth it. If I try to 
start KWrite outside of KDE, on 900MHz machine with 30+MiB/s HDD, after 
cleaning caches by running a process that eats all memory and gets killed by 
OOM-killer, I get this:
- kwrite run normally, i.e. kdeinit is started, kbuildsycoca is run, etc. : 
9,5s
- with this patch: 8s
- first kdeinit is run, then caches are cleaned, then kwrite is run (i.e. only 
actually KWrite startup with cold caches) : 6,5s

 Which shows it's not that big improvement. The most expensive thing seems to 
be actually getting all the other stuff from the HDD (libraries, whatever). 
Note however that benchmarking anything with cold caches gives rather varying 
results, so the numbers are hardly exact.

 The price paid for this feature is that if a .desktop file is changed or a 
new one is installed, kbuildsycoca won't notice. Cases like ksycoca missing, 
having old version or similar are handled fine, also 60sec later kbuildsycoca 
is rebuilt normally and KDirwatch is setup, so this is probably not that big 
problem, but still it could cause trouble. It could be further reduced by 
changing make install and packages to touch 
$KDEDIR/share/services/update_ksycoca , but that wouldn't work with old KDE 
apps and non-KDE apps.

 The GUI (which doesn't exist yet) should be basically a checkbox in the 
Performance kcm, with a 'Warning:dangerous!" or similar next to it, and a 
pushbutton to run kbuildsycoca.

 Alternative solution for "faster" startup of KDE apps outside of KDE would be 
making the timeout for automatic kdeinit shutdown after last KDE application 
goes away much longer, but then there's the problem with the X connections 
blocking 'ssh -X' logout :(.

 Comments, suggestions, yes/no?

PS: In case the patch goes in, it could use some checking. It's probably way 
too hackish.

-- 
Lubos Lunak
KDE developer
---------------------------------------------------------------------
SuSE CR, s.r.o.  e-mail: l.lunak@suse.cz , l.lunak@kde.org
Drahobejlova 27  tel: +420 2 9654 2373
190 00 Praha 9   fax: +420 2 9654 2374
Czech Republic   http://www.suse.cz/

["kded.patch" (text/x-diff)]

--- kded/kded.cpp.sav	2004-09-23 17:04:47.000000000 +0200
+++ kded/kded.cpp	2004-09-23 17:47:13.257681993 +0200
@@ -56,6 +56,7 @@
 Kded *Kded::_self = 0;
 
 static bool checkStamps = true;
+static bool delayedCheck = false;
 
 static void runBuildSycoca(QObject *callBackObj=0, const char *callBackSlot=0)
 {
@@ -63,7 +64,10 @@ static void runBuildSycoca(QObject *call
    args.append("--incremental");
    if(checkStamps)
       args.append("--checkstamps");
-   checkStamps = false; // useful only during kded startup
+   if(delayedCheck)
+      args.append("--nocheckfiles");
+   else
+      checkStamps = false; // useful only during kded startup
    if (callBackObj)
    {
       QByteArray data;
@@ -94,7 +98,8 @@ static void runDontChangeHostname(const 
 
 Kded::Kded(bool checkUpdates)
   : DCOPObject("kbuildsycoca"), DCOPObjectProxy(),
-    b_checkUpdates(checkUpdates)
+    b_checkUpdates(checkUpdates),
+    m_needDelayedCheck(false)
 {
   _self = this;
   QCString cPath;
@@ -339,6 +344,8 @@ void Kded::updateResourceList()
   delete KSycoca::self();
 
   if (!b_checkUpdates) return;
+  
+  if (delayedCheck) return;
 
   QStringList dirs = KSycoca::self()->allResourceDirs();
   // For each resource
@@ -373,25 +380,42 @@ void Kded::installCrashHandler()
 
 void Kded::recreate()
 {
-   recreate(true); // Async
+   recreate(false);
 }
 
-void Kded::recreate(bool async)
+void Kded::runDelayedCheck()
+{
+   if( m_needDelayedCheck )
+      recreate(false);
+   m_needDelayedCheck = false;
+}
+
+void Kded::recreate(bool initial)
 {
    m_recreateBusy = true;
    // Using KLauncher here is difficult since we might not have a
    // database
 
-   updateDirWatch(); // Update tree first, to be sure to miss nothing.
-
-   if (async)
+   if (!initial)
    {
+      updateDirWatch(); // Update tree first, to be sure to miss nothing.
       runBuildSycoca(this, SLOT(recreateDone()));
    }
    else
    {
+      if(!delayedCheck)
+         updateDirWatch(); // this would search all the directories
       runBuildSycoca();
       recreateDone();
+      if(delayedCheck)
+      {
+         // do a proper ksycoca check after a delay
+         QTimer::singleShot( 60000, this, SLOT( runDelayedCheck()));
+         m_needDelayedCheck = true;
+         delayedCheck = false;
+      }
+      else
+         m_needDelayedCheck = false;
    }
 }
 
@@ -811,6 +835,7 @@ extern "C" int kdemain(int argc, char *a
      bool bCheckUpdates = config->readBoolEntry("CheckUpdates", true);
      bool bCheckHostname = config->readBoolEntry("CheckHostname", true);
      checkStamps = config->readBoolEntry("CheckFileStamps", true);
+     delayedCheck = config->readBoolEntry("DelayedCheck", false);
 
      Kded *kded = new Kded(bCheckSycoca); // Build data base
 
@@ -818,7 +843,7 @@ extern "C" int kdemain(int argc, char *a
      signal(SIGHUP, sighandler);
      KDEDApplication k;
 
-     kded->recreate(false);
+     kded->recreate(true); // initial
 
      if (bCheckUpdates)
         (void) new KUpdateD; // Watch for updates
--- kded/kded.h.sav	2004-09-23 17:04:47.000000000 +0200
+++ kded/kded.h	2004-09-23 17:27:12.000000000 +0200
@@ -71,7 +71,7 @@ public:
    bool isWindowRegistered(long windowId);
    void registerWindowId(long windowId);
    void unregisterWindowId(long windowId);
-   void recreate(bool async);
+   void recreate(bool initial);
    /**
     * Loads / unloads modules according to config.
     */
@@ -125,6 +125,8 @@ protected slots:
     * @internal Installs crash handler
     */
    void installCrashHandler();
+   
+   void runDelayedCheck();
 
 protected:
    /**
@@ -161,6 +163,7 @@ protected:
    QAsciiDict<QValueList<long> > m_windowIdList;
    QIntDict<long> m_globalWindowIdList;
    QStringList m_allResourceDirs;
+   bool m_needDelayedCheck;
      
    static Kded *_self;
 };
--- kded/kbuildsycoca.cpp.sav	2004-09-23 17:04:47.000000000 +0200
+++ kded/kbuildsycoca.cpp	2004-09-23 17:04:52.000000000 +0200
@@ -695,6 +695,7 @@ static KCmdLineOptions options[] = {
    { "nosignal", I18N_NOOP("Do not signal applications to update"), 0 },
    { "noincremental", I18N_NOOP("Disable incremental update, re-read everything"), 0 },
    { "checkstamps", I18N_NOOP("Check file timestamps"), 0 },
+   { "nocheckfiles", I18N_NOOP("Disable checking files (dangerous)"), 0 },
    { "global", I18N_NOOP("Create global database"), 0 },
    { "menutest", I18N_NOOP("Perform menu generation test run only"), 0 },
    { "track <menu-id>", I18N_NOOP("Track menu id for debug purposes"), 0 },
@@ -797,9 +798,10 @@ extern "C" int kdemain(int argc, char **
    }
    fprintf(stderr, "%s running...\n", appName);
 
+   bool checkfiles = bGlobalDatabase || args->isSet("checkfiles");
 
-   bool incremental = !bGlobalDatabase && args->isSet("incremental");
-   if (incremental)
+   bool incremental = !bGlobalDatabase && args->isSet("incremental") && checkfiles;
+   if (incremental || !checkfiles)
    {
      KSycoca::self()->disableAutoRebuild(); // Prevent deadlock
      QString current_language = KGlobal::locale()->language();
@@ -812,13 +814,14 @@ extern "C" int kdemain(int argc, char **
          (KSycoca::self()->timeStamp() == 0))
      {
         incremental = false;
+        checkfiles = true;
         delete KSycoca::self();
      }
    }
    
    g_changeList = new QStringList;
 
-   bool checkstamps = incremental && args->isSet("checkstamps");
+   bool checkstamps = incremental && args->isSet("checkstamps") && checkfiles;
    Q_UINT32 filestamp = 0;
    QStringList oldresourcedirs;
    if( checkstamps && incremental )
@@ -858,7 +861,7 @@ extern "C" int kdemain(int argc, char **
 
    newTimestamp = (Q_UINT32) time(0);
 
-   if( !checkstamps || !KBuildSycoca::checkTimestamps( filestamp, oldresourcedirs ))
+   if( checkfiles && ( !checkstamps || !KBuildSycoca::checkTimestamps( filestamp, oldresourcedirs )))
    {
       QCString qSycocaPath = QFile::encodeName(sycocaPath());
       cSycocaPath = qSycocaPath.data();


_______________________________________________
Kde-optimize mailing list
Kde-optimize@kde.org
https://mail.kde.org/mailman/listinfo/kde-optimize


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic