QML是在编译时翻译成本机代码还是在运行时按照在Web浏览器中运行JavaScript的方式进行解释?

Iva*_*van 16 c++ qt qml

QML是在编译时翻译成本机代码还是在运行时解释几乎与在Web浏览器中运行JavaScript的方式相同?

mlo*_*kot 5

AFAIK,在Qt文档中似乎没有直接和详细的解释,但一些Qt黑客试图解释它:

QML被编译为优化的类字节码流,JavaScript表达式通过优化的评估器来处理简单表达式.

还有相关的QTBUG任务QtQuick启动时间需要改进; 在运行之间缓存已编译的QML

我的理解是QML状态还没有完全解决,工程师也没有说明它是固定的,因此他们将来可以自由地改进它.

ATM,最好的建议是将C++与QML混合,使用C++中的所有应用程序逻辑和QML中的表示,但理想情况下分为较小的QML文件,而不是单个大型QML文件.


gur*_*ruz 5

有了 Qt 5.3 和企业许可证,实际上有一种方法可以对其进行预编译。

https://doc.qt.io/QtQuickCompiler/

这对于 Apple 不允许 JIT 代码生成的 iOS 很有用。


tan*_*ius 5

我刚刚有同样的问题,几年后现在的情况是这样的:

\n

现状(Qt 5.15)

\n

Qt 5 中最先进的技术是使用提前 QML 编译。这使用了 QuickCompiler,这是一个“在 Qt 5.3 中为商业被许可方引入的工具,包括 Qt 5.11 中的商业和开源”(来源)。从QtQuickCompiler 的旧文档中可以更清楚地了解它的实际用途:

\n
\n

[没有 QtQuickCompiler] 流行的即时 (JIT) 编译技术用于动态生成机器代码 [从 QML],从而加快 JavaScript 和 QML 绑定表达式的执行速度。

\n

不幸的是,这种方法有一些缺点: [\xe2\x80\xa6] 某些平台版本(例如 iOS 或 Windows RT)不允许动态生成机器代码。[\xe2\x80\xa6]

\n

编译的 Qt Quick [通过 QtQuickCompiler] 是解决这些问题的优雅解决方案:.qml 文件以及随附的 .js 文件可以转换为中间 C++ 源代码。使用传统编译器编译后,代码将链接到应用程序二进制文件中。

\n
\n

使用 QtQuickCompiler 进行的提前编译生成的字节码与实时 (JIT) 编译在运行时从 QML 生成的字节码相同。QtQuickCompiler 确实生成“中间 C++ 源代码”,但这只是 C++ 数据结构中的字节码,要嵌入到生成的 C++ 可执行文件中。我测试过;要亲自查看它,您只需构建一个启用 QtQuickCompiler 的 Qt Quick 项目,然后{filename}_qml.cpp在构建目录中打开文件,该文件已为您的{filename}.qml. 它看起来像这样:

\n
// /{filename}.qml\nnamespace QmlCacheGeneratedCode {\n    namespace _0x5f__main_qml {\n        extern const unsigned char qmlData alignas(16) [] = {\n            0x71,0x76,0x34,0x63,0x64,0x61,0x74,0x61,\n            0x20,0x0,0x0,0x0,0x4,0xc,0x5,0x0,\n            // \xe2\x80\xa6 many many more lines \xe2\x80\xa6\n            0x40,0x0,0x40,0x1,0x40,0x0,0xf0,0x1,\n            0x0,0x0,0x0,0x0\n        };\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

因此,在 Qt 5 中,QML 既不会在编译时翻译为本机 [C++] 代码,也不会在运行时解释。相反,它被提前编译为字节码。然后,该字节码将在小型 JavaScript 虚拟机中运行,类似于 JVM 中的 Java 字节码。虚拟机总是需要的,因为从 QML / JavaScript 等弱类型语言编译机器代码是不可能的。

\n

当 QtQuickCompiler 和带有缓存的 JIT 编译都不可用时,“QML 提供了一个解释器来允许充分使用 QML,但它是以更长的执行时间为代价的。” (来源

\n

未来情况(Qt 6)

\n

计划 Qt 6 的未来版本确实将包括 QML 到本机 C++ 代码的翻译,然后像任何其他 C++ 代码一样进行编译:

\n
\n

支持将 QML 编译为高效的 C++ 和本机代码。借助强大的类型和更简单的查找规则,我们可以将 QML 转换为高效的 C++ 和本机代码,从而显着提高运行时性能。(来源

\n
\n

我不得不说,这听起来很棒:)

\n