Index: kdevplatform/shell/projectcontroller.cpp =================================================================== --- kdevplatform/shell/projectcontroller.cpp +++ kdevplatform/shell/projectcontroller.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -62,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +109,9 @@ bool m_cleaningUp; //Temporary flag enabled while destroying the project-controller QPointer m_changesModel; QHash< IProject*, QPointer > m_parseJobs; // parse jobs that add files from the project to the background parser. + QList m_finaliseProjectImports; // project dir watchers and/or parse jobs waiting to be started + QHash m_timers; // TEMPORARY: project load timers + static QElapsedTimer m_timer; // TEMPORARY: session-wide project load timer explicit ProjectControllerPrivate( ProjectController* p ) : m_core(nullptr), model(nullptr), dialog(nullptr), q(p), buildset(nullptr), m_foundProjectFile(false), m_cleaningUp(false) @@ -311,6 +316,11 @@ return; } + if (!m_timer.isValid()) { + m_timer.start(); + qCWarning(SHELL) << "Starting project import timer"; + } + foreach( IProject* project, m_projects ) { if ( url == project->projectFile().toUrl() ) @@ -329,6 +339,11 @@ m_core->pluginControllerInternal()->loadProjectPlugins(); Project* project = new Project(); + // TEMPORARY: initialise project load timer + if (qEnvironmentVariableIsSet("KDEV_DONT_DEFER_PROJECT_PARSING")) { + m_timers[project] = new QElapsedTimer; + m_timers[project]->start(); + } QObject::connect(project, &Project::aboutToOpen, q, &ProjectController::projectAboutToBeOpened); if ( !project->open( Path(url) ) ) @@ -346,6 +361,8 @@ } }; +QElapsedTimer ProjectControllerPrivate::m_timer; + IProjectDialogProvider::IProjectDialogProvider() {} @@ -897,7 +914,39 @@ d->m_currentlyOpening.removeAll(project->projectFile().toUrl()); emit projectOpened( project ); - reparseProject(project); + // don't call reparseProject immediately, defer until all currently opening + // projects have been imported. Parsing is done in the background but + // importing can block the UI so should be as fast as possible. + // TEMPORARY: deferFinalise + bool deferFinalise = !qEnvironmentVariableIsSet("KDEV_DONT_DEFER_PROJECT_WATCHING_AND_PARSING"); + if (d->m_currentlyOpening.isEmpty()) { + if (deferFinalise) { + qCInfo(SHELL) << "All projects imported in" << ProjectControllerPrivate::m_timer.restart() / 1000.0 << "seconds"; + reparseProject(project); + foreach (const auto p, d->m_finaliseProjectImports) { + reparseProject(p); + } + qCInfo(SHELL) << "\tstarting parse jobs took an additional" + << ProjectControllerPrivate::m_timer.elapsed() / 1000.0 << "seconds"; + } + d->m_finaliseProjectImports.clear(); + ProjectControllerPrivate::m_timer.invalidate(); + } else { + if (deferFinalise) { + d->m_finaliseProjectImports.append(project); + } + } + if (!deferFinalise) { + QElapsedTimer *timer = d->m_timers[project]; + qCInfo(SHELL) << "Project" << project->name() << "imported in" + << timer->restart() / 1000.0 << "seconds"; + reparseProject(project); + qCInfo(SHELL) << "\t" << project->name() + << ": starting parse jobs took an additional" + << timer->elapsed() / 1000.0 << "seconds"; + delete timer; + d->m_timers[project] = 0; + } } // helper method for closeProject() @@ -956,6 +1005,7 @@ // loading might have failed d->m_currentlyOpening.removeAll(proj->projectFile().toUrl()); d->m_projects.removeAll(proj); + d->m_finaliseProjectImports.removeAll(proj); emit projectClosing(proj); //Core::self()->saveSettings(); // The project file is being closed. // Now we can save settings for all of the Core