QML是在编译时被翻译成本机代码,还是在运行时被解释为JavaScript在web浏览器中的运行方式
Is QML translated into native code at the compilation time or is it interpreted at runtime the way JavaScript is ran in web browsers?
QML是在编译时被翻译成本机代码,还是在运行时几乎像在web浏览器中运行JavaScript一样被解释?
AFAIK,Qt文档中似乎没有直接而详细的解释,但一些Qt黑客试图解释它:
QML被编译为优化的类似字节码的流JavaScript表达式通过优化的计算器表达式。
还有相关的QTBUG任务Qt快速启动时间有待提高;运行之间缓存编译的QML
我的理解是,QML的状态还没有完全解决,工程师们也没有宣布它是固定的,所以他们可以自由地在未来改进它。
ATM,最好的建议是将C++与QML混合,将所有应用程序逻辑都用C++表示,并用QML表示,但最好将其划分为较小的QML文件,而不是单个大型QML文件。
有了Qt 5.3和企业许可证,实际上有一种方法可以预编译它。
https://doc.qt.io/QtQuickCompiler/
这对于苹果不允许JIT代码生成的iOS非常有用。
我刚刚有同样的问题,几年后的情况如下:
现状(5.15 Qt)
Qt5中最先进的技术是使用提前QML编译。这使用了QuickCompiler;在Qt 5.3中为商业许可证持有者引入,在Qt 5.11";(来源)。从QtQuickCompiler的旧文档中,它的实际功能变得更加清晰:
[没有QtQuickCompiler,]流行的实时(JIT)编译技术用于[从QML]动态生成机器代码,从而加快JavaScript和QML绑定表达式的执行。
不幸的是,这种方法有一些缺点:[…]一些平台版本,如iOS或Windows RT,不允许动态生成机器代码。[…]
编译的QtQuick[通过QtQuickCompiler]是解决这些问题的一个优雅的解决方案:.qml文件以及附带的.js文件可以转换为中间C++源代码。使用传统编译器编译后,代码将链接到应用程序二进制文件中。
这种使用QtQuickCompiler的提前编译会产生与实时(JIT)编译在运行时从QML产生的字节码相同的字节码。QtQuickCompiler确实产生了";中间C++源代码";,但这只是C++数据结构中的字节码,要嵌入到生成的C++可执行文件中。我测试了它;要亲自查看,只需在启用QtQuickCompiler的情况下构建一个QtQuick项目,然后在构建目录中打开为{filename}.qml
生成的文件{filename}_qml.cpp
。它看起来是这样的:
// /{filename}.qml
namespace QmlCacheGeneratedCode {
namespace _0x5f__main_qml {
extern const unsigned char qmlData alignas(16) [] = {
0x71,0x76,0x34,0x63,0x64,0x61,0x74,0x61,
0x20,0x0,0x0,0x0,0x4,0xc,0x5,0x0,
// … many many more lines …
0x40,0x0,0x40,0x1,0x40,0x0,0xf0,0x1,
0x0,0x0,0x0,0x0
};
}
}
因此,在Qt5中,QML既没有在编译时被翻译成本机[C++]代码,也没有在运行时被解释。相反,它会提前编译为字节码。然后,这个字节码将在一个用于JavaScript的小型虚拟机中运行,类似于JVM中使用Java字节码所做的操作。总是需要虚拟机,因为从QML/JavaScript这样的弱类型语言编译机器代码是不可能的。
当QtQuickCompiler和带有缓存的JIT编译都不可用时;QML提供了一个解释器以允许充分使用QML,但这是以较长的执行时间为代价的"(来源)
未来情况(第6季度)
据计划,Qt6的未来版本确实将包括QML翻译成本机C++代码,然后像编译任何其他C++代码一样进行编译:
支持将QML编译为高效的C++和本机代码通过强大的类型和更简单的查找规则,我们可以将QML转换为高效的C++和本机代码,从而显著提高运行时性能。(来源)
我不得不说,这听起来很棒:)
编译的语言和解释的语言之间有很大的区别。QML文档由QML运行时进行解释。从某种意义上说,可以说它是像JavaScript一样执行的。
QML运行时包括QML引擎、JavaScript引擎和绑定到Qt框架的机制。
Qt快速编译器™Qt 6.3
新的Qt快速编译器将由两个组件组成:QML类型编译器和QML脚本编译器。QML类型编译器将把QML对象结构编译成C++类。QML脚本编译器将把应用程序的QML文件中的函数和表达式编译成C++代码。尽可能多,因为JavaScript的性质会设置一些限制。如果某些语句无法编译,则将使用常规解释和缓存。。。。。(来源)
- 如何在本地机器上运行c++和javascript客户端代码(hackerbank风格)
- 如何将C++闭包与变量参数同时重用——类似于JavaScript
- 用于将C++代码转换为 Web 程序集的脚本未终止
- 嘿,我正在尝试将此c ++转换为javascript,但有些东西不起作用
- C# DLL 从C++应用程序调用 SOAP Web 服务
- C++中的 JavaScript 样式闭包
- OpenCV(C++)处理来自JavaScript / Web Assembly的图像数据
- 在C++中嵌入 Mozilla 的 JavaScript 引擎
- Javascript 找不到使用 emscripten 编译的导出 WASM 函数
- 用于 progmem 的C++和头文件压缩的 Web 文件字节数组
- 来自带有mbedtls TLS的Mongoose Web服务器的错误消息
- 在Javascript和C++中计算MD5哈希的不同结果
- 将Wiimote MAC地址转换为PIN码,从C++转换为Python或Javascript
- 如何使用EM_JS从带有参数的C++调用javascript方法
- JavaScript 中的一等函数和 C++ 中的函数声明
- 使用 ESP8266/8285 将字符串从 Web 服务器转换为字节数组
- 如何直接从本机JavaScript Front与Emscripten Web Worker进行互动
- 使用Emscripten C Web Worker的大型阵列有效传输:JavaScript设计更好
- QML是在编译时被翻译成本机代码,还是在运行时被解释为JavaScript在web浏览器中的运行方式
- 嵌入式 Web 控件 (IWebBrowser2),嵌入式 JavaScript 的 onkeydown 和 onkeyup 不触发