Chris Howells wrote:
Hi,

bat is rather slow for me with loading very large backups into the restore window. I therefore did some profiling of it using KCacheGrind (which uses callgrind, part of valgrind).

Hi,

Attached is an updated patch which removes more QRegExp. The profiling shows that calling QProgressBar::setText() is also *fairly* expensive;
previously bat seemed to be doing this for every single file, which was
quite bad. bat now only updated the progress bar for every 1000 items. You won't notice any difference in terms of UI, other than it will be quicker to load a job. Also I've tried to stick exactly to the existing coding style which I failed a bit in the first patch :)

With this patch loading a 450GB backup (2.7million files) into bat now takes 280 seconds for me, rather than 466 seconds. That's nearly a 40% improvement.

If anybody can verify that the patch doesn't cause any regressions, and
also provides a similar performance boost, I'd be grateful if it could
go into SVN :)

The profiling stats suggest that there is still some more optimisation that can be done, but these were the easy pickings.


Index: restore/restoretree.cpp
===================================================================
--- restore/restoretree.cpp	(revision 5623)
+++ restore/restoretree.cpp	(working copy)
@@ -53,7 +53,6 @@
    dockPage();
    m_winRegExpDrive.setPattern("^[a-zA-Z]:/$");
    m_winRegExpPath.setPattern("^[a-zA-Z]:/");
-   m_slashregex.setPattern("/");
    m_debugCnt = 0;
    m_debugTrap = true;
 
@@ -260,7 +259,9 @@
          QStringList fieldlist;
          foreach(QString resultline, results) {
             m_debugCnt += 1;
-            prBar2->setValue(m_debugCnt);
+            /* Calling QProgressBar::setValue() is really quite expensive - only do it every 1000 items */
+            if (m_debugCnt % 1000 == 0)
+               prBar2->setValue(m_debugCnt);
             fieldlist = resultline.split("\t");
             int fieldcnt = 0;
             QString field;
@@ -329,10 +330,10 @@
    if (m_debugCnt > 2)
       m_debugTrap = false;
    /* Clean up the directory string remove some funny char after last '/' */
-   QRegExp rgx("[^/]$");
-   int lastslash = rgx.indexIn(dir_in);
-   if (lastslash != -1)
-      dir_in.replace(lastslash, dir_in.length()-lastslash, "");
+   /* if the final character isn't a /, truncate everything after it */
+   if (dir_in.right(1) != "/")
+      dir_in.truncate(dir_in.lastIndexOf("/") + 1);
+
    if ((mainWin->m_miscDebug) && (m_debugTrap))
       Pmsg1(000, "parsing %s\n", dir_in.toUtf8().data());
 
@@ -341,10 +342,10 @@
    int index;
    bool done = false;
    QStringList pathAfter, dirAfter;
-   /* start from the end, turn /etc/somedir/subdir/ into /etc/somedir and subdir/ 
+   /* start from the end, turn /etc/somedir/subdir/ into /etc/somedir and subdir/
     * if not added into tree, then try /etc/ and somedir/ if not added, then try
     * / and etc/ .  That should succeed, then add the ones that failed in reverse */
-   while (((index = m_slashregex.lastIndexIn(dir_in, -2)) != -1) && (!done)) {
+   while (((index = dir_in.lastIndexOf("/", -2)) != -1) && (!done)) {
       direct = path = dir_in;
       path.replace(index+1, dir_in.length()-index-1,"");
       direct.replace(0, index+1, "");
@@ -1280,7 +1281,7 @@
    bool done = false;
    QString fullPath = fullPath_in;
    QString direct, path;
-   while (((index = m_slashregex.lastIndexIn(fullPath, -2)) != -1) && (!done)) {
+   while (((index = fullPath.lastIndexOf("/", -2)) != -1) && (!done)) {
       direct = path = fullPath;
       path.replace(index+1, fullPath.length()-index-1, "");
       direct.replace(0, index+1, "");
@@ -1730,7 +1731,7 @@
 {
    int qversion = 0;
    QString directory, fileName;
-   int index = m_slashregex.lastIndexIn(fullPath, -2);
+   int index = fullPath.lastIndexOf("/", -2);
    if (index != -1) {
       directory = fileName = fullPath;
       directory.replace(index+1, fullPath.length()-index-1, "");
@@ -1783,7 +1784,7 @@
 {
    int qfileIndex = 0;
    QString directory, fileName;
-   int index = m_slashregex.lastIndexIn(fullPath, -2);
+   int index = fullPath.lastIndexOf("/", -2);
    if (index != -1) {
       directory = fileName = fullPath;
       directory.replace(index+1, fullPath.length()-index-1, "");
Index: restore/restoretree.h
===================================================================
--- restore/restoretree.h	(revision 5623)
+++ restore/restoretree.h	(working copy)
@@ -102,7 +102,6 @@
    bool m_dropdownChanged;
    QRegExp m_winRegExpDrive;
    QRegExp m_winRegExpPath;
-   QRegExp m_slashregex;
    bool m_slashTrap;
    QHash<QString, QTreeWidgetItem *> m_dirPaths;
    QString m_checkedJobs, m_prevJobCombo, m_prevClientCombo, m_prevFileSetCombo;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Bacula-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bacula-devel

Reply via email to