我最近切换到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个值:
在init进程中调用update()函数7次,但实际上只有前两次调用非常慢。
我还注意到,如果我在init之前调用QCoreApplication::libraryPaths()
,那么前4个update()
调用只返回前两个路径,这就解决了问题。
我现在有一个解决方案,这很棒,但我想了解为什么这个有效,并找到一个不那么笨拙的解决方案。
答案 0 :(得分:2)
没有特定环境的答案是一个非常普遍的问题:
如何改善Qt5程序的启动时间?
......真的不能在这里给出。大多数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 ¶mList, 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还是自定义插件。
答案 1 :(得分:1)
我不会从调试开始(因为,我会冒险,你可能会在某个地方遇到高度争议的锁定并且调试赢了很多)
我建议首先对您的代码进行良好的分析,并且我知道没有比Bruce Dawson的工具/文档更好的了解
开始here并继续分析您的应用
答案 2 :(得分:0)
简短答案:将二进制文件部署到子文件夹中。
长答案:我遇到了同样的问题,并查找了Qt源代码,它将附加应用程序目录以查找插件。因此,除非有人提出合并请求,否则别无选择,只能将应用程序放在一个文件夹中(如果我有空闲时间,我会尝试自己做)。