Version: (using KDE KDE 3.5.7) Installed from: Debian testing/unstable Packages OS: Linux Now that the ping-pong of source changes related to bug 148229 ended, it is time to further optimize FileTreeWidget implementation, to make startup time of KDevelop on large projects acceptable. FileTreeWidget::addProjectFiles() method spends considerable share of its time re-inserting directories in an attempt to build the full project file tree, especially on projects with less-than-trivial directory structure. See the fully commented patch below.
Created attachment 21315 [details] Early-out in directory insertion for project tree creation.
For some reason, the bug system's initial Wizard did not guided me to fill the proper Version tag for this bug. The change / patch applies on KDevelop 3.4.1 / SVN version.
SVN commit 695144 by apaku: Speedup project loading by exiting the loop earlier. Patch from opal@scssoft.com BUG:148426 M +23 -3 filetreewidget.cpp M +4 -0 filetreewidget.h --- branches/KDE/3.5/kdevelop/parts/fileview/filetreewidget.cpp #695143:695144 @@ -238,6 +238,18 @@ /////////////////////////////////////////////////////////////////////////////// +/** + * @brief Add a bunch of files to this project. + * + * Whenever we load a project or user chooses to add a bunch of files using UI, + * we end in this method. + * We merge the list of files already in the project (if any) with the incoming set. + * + * @param fileList + * @param constructing + * + * @see m_projectFiles + */ void FileTreeWidget::addProjectFiles( QStringList const & fileList, bool constructing ) { kdDebug(9017) << "files added to project: " << fileList << endl; @@ -248,15 +260,23 @@ if( (*it).isEmpty() ) continue; kdDebug(9017) << "adding file: " << *it << endl; - QString file = projectDirectory() + "/" + ( *it ); + const QString file = projectDirectory() + "/" + ( *it ); if ( !m_projectFiles.contains( file ) ) { + // We got a new file to add to this project. + // Ensure all the parent directories are part of the project set, too. QStringList paths = QStringList::split( "/", *it); paths.pop_back(); while( !paths.isEmpty() ) { - if( !m_projectFiles.contains( paths.join("/") ) ) - m_projectFiles.insert( projectDirectory() + "/" + paths.join("/"), true ); + // We are adding the directories from longest (the one containing our file), + // to the shortest, measured from root directory of our project. + // Whenever we find out that a directory is already recorded as part of our project, + // we may stop adding, because its parent directories were already added - + // in some previous addition. + if( m_projectFiles.contains( paths.join("/") ) ) + break; + m_projectFiles.insert( projectDirectory() + "/" + paths.join("/"), true ); paths.pop_back(); } m_projectFiles.insert( file, false ); --- branches/KDE/3.5/kdevelop/parts/fileview/filetreewidget.h #695143:695144 @@ -90,6 +90,10 @@ /** * @brief Set of all the files in this project. * + * In addition to all the project files, + * we also keep a list of all directories containing any project files - + * effectively holding the whole project tree. + * * @bug * Well, it is not just a plain set, * but rather a map with next-to-useless element value,