原文链接:Lars Knoll – Evolution of the QML engine, part 1

QML作为一项技术对于Qt的成功变得越来越重要。它允许创建流畅的动画界面,与现今的市场预期相符。有三个主要的特性使得它更适合创建用户界面。首先是声明式语法,使得它非常容易创建用户界面,并且开发者和UI设计者工作在相同的代码基础上。其次,这项技术使原生代码集成变得相对容易,它承担了更多的程序逻辑以及C++所负的重任。最后,选择JavaScript作为QML语言不可分割的一部分,这样使得创建原型更加容易,并且为更广泛的用户提供了新技术。

今天的引擎是相当棒的基石并且满足了大多数用户的需求。当然也有一些我们需要在未来解决的短处和问题。这个系列的博客将概括我们的研究并且呈现我们计划要实现的解决方案。目标是在将来得到一个更好、更灵活、更易维护的QML引擎。

让我从当前引擎所面对的一些问题开始。

  • 多个对象模型

    当前的QML引擎使用V8 JavaScript引擎来执行属性绑定。每个QML项内部有几个不同的表示。一个面向V8(使用公开的V8 API),一个面向QML引擎,还有一个作为QObject暴露给原生Qt。这里的问题是需要QML引擎来同步这些不同的表示,导致了大量的中间代码和相当高的内存消耗来维持这些不同的表示。

  • 通过JS闭包(closures)完成绑定

    使用V8每个绑定需要一个JS函数闭包。这需要把这个表达式重写成闭包,然后让V8再次解析这个重写的表达式。在V8中评估绑定需要调用JS函数,它使用大量的额外开销来模拟执行绑定的上下文环境。因此在我们开发小型的用于QML引擎中的表达式解析器(叫做V4)的时候,它可以计算简单的表达式,这个解释器比通过V8计算快很多倍。

  • 数据类型转换

    使用V8计算表达式很慢的一个原因是从Qt到V8或者从V8到Qt数据类型转换带来的额外开销。读写一个Qt属性,例如创建一个QVariant,将被转换为V8::Value。如果这个QVariant是字符串,将会调用字符串数据的复制。为了减弱这些开销引进了各种缓存机制,但是随之而来的是内存使用以及代码复杂性的增加。

  • QML域规则

    QML语法上是项目树。内部项可以隐式查看外部项的属性,形成了一个良好定义的作用域链。不幸的是这个作用域链和传统的JavaScript不同,不能用现有的JavaScript引擎直接实现。直接实现的唯一方法是嵌入慢的不被赞成(deprecated)的with()语句。目前的解决方案包含了一个暴力(intrusive)补丁在V8中,并且仍然需要通过名字来查找所有的QML属性。

  • QML类型信息的丢弃

    QML作为一种语言拥有类型信息。但是JavaScript是完全无类型的。导致了这样一个事实,所有的类型信息在QML编译时被丢弃。保留这些类型信息将使我们更好的优化QML表达式。

  • iOS和WinRT支持

    iOS不允许内存可执行和可写,而这正是现有JS引擎所需的。WinRT根本不允许使内存可执行。这样的情况下,如果不写一个完整的V8解释器后端,就不能在这些平台上使用V8。

  • 和V8上游一起工作

    如上所述,我们当前被迫维护一个相当大并且暴力的补丁集在V8之上。根本没有机会把这些标补丁合并到上游,因为V8专注于浏览器应用。

这些不同的问题导致了一个研究项目,大约一年前由Nokia的Roberto Raggi和Aaron Kennedy发起。他们考察了根据QML的需求裁剪JS引擎的的可能性。这个项目代号为v4vm,之后被转移到Digia,Simon、Erik和我重拾这个项目并且继续研究。它作为一个playground项目存在于qt-project.org,已经有好几个月了。

今天我们把这个研究项目集成到了Qt Declarative的一个开发分支,从现在开始我们将在这个分支继续工作。

新的引擎包含了一个完全遵循ECMAScript 5.1的实现,它可以运行于所有Qt支持的平台。它包含了一个JIT,目前可以工作在Linux、Mac和iOS。 目前已经完成了到当前QML引擎的集成,是通过一个兼容的V8 API层实现的,我们计划在未来几周移除它。这个引擎可以运行所有的Qt Quick演示程序(有一些小问题)。

值得注意的一件事是,这个引擎专注于QML使用。这意味着我们期望QML的性能变得比今天的更好。从另一方面讲,纯JS性能并不一定像V8那样好。

然而我们当前的基准数据(benchmark numbers)和纯JS代码一样是非常有希望的,V8基准大约慢于Qt 4.8和Qt Quick 1中JS引擎3倍。我们看到了很大潜力,可以在将来优化。

新引擎的细节和我们未来的计划将在接下来的几篇文章中介绍。您可以在qtdeclarative的wip/v4分支找到代码。随意尝试吧。

QML引擎的演进,第一部分的更多相关文章

  1. 深入解析QML引擎, 第4部分: 自定义解析器

    原文 QML Engine Internals, Part 4: Custom Parsers ——————————————————————————————————————————— 上一篇 绑定类型 ...

  2. 深入解析QML引擎, 第2部分: 绑定(Bindings)

    原文  QML Engine Internals, Part 2: Bindings 译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/QML爱好 ...

  3. 深入解析QML引擎, 第3部分: 绑定类型

    原文 QML Engine Internals, Part 3: Binding Types 译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/Q ...

  4. 深入解析QML引擎, 第1部分:QML文件加载

    译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/QML爱好者和工作者也能更好的学习和理解QML引擎,故将这个系列的4篇文章翻译过来.翻译并不是完 ...

  5. 深度解析qml引擎---(2)绑定(binding)

    强烈的希望是人生中比任何欢乐更大的兴奋剂.--尼采 上一篇文章讲了QML引擎加载qml文件的过程,大体过程是,解析qml文件,然后为文件中的每个元素创建对应的c++对象.例如,qml文件中如果使用了T ...

  6. 深度解析qml引擎---(1)Qml文件加载

                                                                        "美的事物是永恒的喜悦" --- 济慈    ...

  7. cocos2d-x_下载游戏引擎并创建第一个项目

    我是一名小白. 下载并创建游戏项目 第一步:去官网下载cocos2d-x http://www.cocos.com/download 第二步:将安装包里边的 setup.py 拖进命令行点击回车键 , ...

  8. QML和JS引擎的关系以及调用c++函数的原理

    首先推荐几篇博客 1.深入解析QML引擎, 第1部分:QML文件加载 https://www.cnblogs.com/wzxNote/p/10569535.html 2.深入解析QML引擎, 第2部分 ...

  9. 使用QML创建第一个界面(转)

    原文转自 https://blog.csdn.net/rl529014/article/details/51378307 在Qt编程中,我们可以使用纯C++代码,或C++和XML结合的方式来创建GUI ...

随机推荐

  1. GNOME编辑器--gedit 构建基本脚本

    gedit factorial.sh myprog.c 当你启动gedit外带多个文件时,它会将所有的文件都加载到不同的缓冲区并在主编辑器窗口中按标签化的窗口来显示每个文件. shell脚本的关键在于 ...

  2. mysql-5.7.16 解压版安装

    下载压缩包后,解压到任盘 配置环境变量: 将“C:\MySQL;”加入到环境变量Path中 重命名my-default.ini为my.ini 修改my.ini内容: basedir =C:\MySQL ...

  3. 基于WebDriver&TestNG 实现自己的Annotation @TakeScreenshotOnFailure

    相信用过Selenium WebDriver 的朋友都应该知道如何使用WebDriver API实现Take Screenshot的功能. 在这篇文章里,我主要来介绍对failed tests实现 t ...

  4. 尝试打开或创建物理文件 REATE FILE 遇到操作系统错误 5(拒绝访问)

    尝试打开或创建物理文件 'E:\Library.mdf' 时,CREATE FILE 遇到操作系统错误 5(拒绝访问.). 最佳回答: 这是因为SQL Server的启动帐户(一般是system或某个 ...

  5. MySQL MEM_ROOT详细讲解

    这篇文章会详细解说MySQL中使用非常广泛的MEM_ROOT的结构体,同时省去debug部分的信息,仅分析正常情况下,mysql中使用MEM_ROOT来做内存分配的部分. 在具体分析之前我们先例举在该 ...

  6. 如何在centos 6.7 上安装oracle 11gR2

    1.软件准备: centos6.7(64位); oracle11gR2((Linux x86-64)) 2.执行如下命令安装好相关的包: yum -y install \ binutils \ com ...

  7. IIS 发布添加网站错误:HTTP 错误 500.21 - Internal Server Error 解决方案

    原因:在安装Framework v4.0之后,再启用IIS,导致Framework没有完全安装 解决:开始->所有程序->附件->鼠标右键点击“命令提示符”->以管理员身份运行 ...

  8. LPC2478调试___ads常见错误分析

    进行ADS外部RAM进行仿真调试过程中,出现常见错误“entry point lies  outside the image" 原因为程序空间超出范围,需要修改一个参数. 解决方法:首先在Z ...

  9. shell return value

  10. Spark Streaming中动态Batch Size实现初探

    本期内容 : BatchDuration与 Process Time 动态Batch Size Spark Streaming中有很多算子,是否每一个算子都是预期中的类似线性规律的时间消耗呢? 例如: ...