c++ - 如何改善 Qt5 程序的启动时间?

标签 c++ qt

我最近切换到 Qt5,我注意到与 Qt4 相比,初始化 QApplication 花费的时间明显更长(大约几分钟)。

查看它,该程序似乎将时间花在了这里:

Qt5Guid.dll!QGlobalStatic<QFactoryLoader,&`anonymous namespace'::Q_QGS_directLoader::innerFunction,A0x95ca5a10::Q_QGS_directLoader::guard>::operator()() Line 129   C++
Qt5Guid.dll!QPlatformIntegrationFactory::create(const QString & platform, const QStringList & paramList, int & argc, char * * argv, const QString & platformPluginPath) Line 70 C++
Qt5Guid.dll!init_platform(const QString & pluginArgument, const QString & platformPluginPath, const QString & platformThemeName, int & argc, char * * argv) Line 1019   C++
Qt5Guid.dll!QGuiApplicationPrivate::createPlatformIntegration() Line 1176   C++
Qt5Guid.dll!QGuiApplicationPrivate::createEventDispatcher() Line 1196   C++
Qt5Widgetsd.dll!QApplicationPrivate::createEventDispatcher() Line 197   C++
Qt5Cored.dll!QCoreApplication::init() Line 769  C++
Qt5Cored.dll!QCoreApplication::QCoreApplication(QCoreApplicationPrivate & p) Line 689   C++
Qt5Guid.dll!QGuiApplication::QGuiApplication(QGuiApplicationPrivate & p) Line 570   C++
Qt5Widgetsd.dll!QApplication::QApplication(int & argc, char * * argv, int _internal) Line 569   C++

基本上每次启动都要花几分钟初始化windows平台插件。

我怎样才能减少或消除这个时间,有人知道原因是什么吗?

我正在使用 Qt 5.5.1 和 VS2012 64 位。

编辑:不确定它是否相关,但我有 QT_QPA_PLATFORM_PLUGIN_PATH="C:\Qt-5.5.1\plugins\platforms\"这是它找到平台插件的方式。

Edit2:进一步调查发现,原因是在初始化程序的过程中,QFactoryLoader::update()扫描了一些目录下的每个文件寻找一种模式。因为该目录包含程序目录,所以它扫描了我的整个程序文件(几个 gb)。

路径由 QCoreApplication::libraryPaths() 确定,它返回 3 个值:

  • C:/Qt-5.5.1/plugins/platforms
  • C:/Qt-5.5.1/plugins
  • C:/MyProject/x64/Debug <-- 问题

update()函数在init进程中被调用了7次,但实际上只有前两次调用很慢。

我还注意到,如果我在初始化之前调用 QCoreApplication::libraryPaths(),那么前 4 个 update() 只会返回前两个路径> 调用,解决了问题。

很高兴我现在有一个解决方案,但我想了解为什么它有效并找到一个不那么 hacky 的解决方案。

最佳答案

很笼统的问题没有特定环境的答案:

How can I improve the startup time of Qt5 programs?

...这里真的不能给出。大多数 Qt 开发人员不会遇到这种延迟。但是我们总是可以尝试调试。所以答案是关于如何调试的。根据您发布的内容,代码位于:qtbase/src/gui/kernel/qplatformintegrationfactory.cpp :

Qt5Guid.dll!QGlobalStatic<QFactoryLoader,&`anonymous namespace'::Q_QGS_directLoader::innerFunction,A0x95ca5a10::Q_QGS_directLoader::guard>::operator()() Line 129   C++
Qt5Guid.dll!QPlatformIntegrationFactory::create(const QString & platform, const QStringList & paramList, int & argc, char * * argv, const QString & platformPluginPath) Line 70 C++

看来调用的函数是:

QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platform, const QStringList &paramList, int &argc, char **argv, const QString &platformPluginPath)
{
#ifndef QT_NO_LIBRARY
    // Try loading the plugin from platformPluginPath first:
    if (!platformPluginPath.isEmpty()) {
        QCoreApplication::addLibraryPath(platformPluginPath);
        if (QPlatformIntegration *ret = loadIntegration(directLoader(), platform, paramList, argc, argv))
            return ret;
    }
    if (QPlatformIntegration *ret = loadIntegration(loader(), platform, paramList, argc, argv))
        return ret;
#endif
    return 0;
}

您可以指向 Qt 的调试版本Qt5Guid.dll 加载符号并使 Qt 源代码可用于调试器和/或 在用于调试项目的机器上自己构建 Qt,并将可执行文件与其链接。然后在第70行打断点:

if (QPlatformIntegration *ret = loadIntegration(directLoader(), platform, paramList, argc, argv))

然后运行程序并调查阻止插件快速加载的原因。从这个上下文来看,甚至不清楚它到底是什么插件,它是 Qt 自带的还是自定义的。

关于c++ - 如何改善 Qt5 程序的启动时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35564370/

相关文章:

c++ - `=default` move 构造函数是否等同于成员 move 构造函数?

c++ - 使用 Qt 绘制像素完美的圆形

c++ - 当我在窗口上动态添加小部件时,我应该指定父级吗?

python - PySide 中的 QStandardItemEditorCreator

c++ - Qt 信号槽,新符号中的类型转换

c++ - 如何在 C++ 中使用指针创建输入法

c++ - namespace std 在哪里定义的?

c++ - 在 Visual Studio 中构建 wxWidgets-3.1.2 项目时如何修复 "Cannot find setup.h"错误?

c++ - C终端程序中的状态行

c++ - 使用 QAction 和 setToolTip() 时的 Qt 本地化问题