QML引擎的演进,第一部分
原文链接: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引擎的演进,第一部分的更多相关文章
- 深入解析QML引擎, 第4部分: 自定义解析器
原文 QML Engine Internals, Part 4: Custom Parsers ——————————————————————————————————————————— 上一篇 绑定类型 ...
- 深入解析QML引擎, 第2部分: 绑定(Bindings)
原文 QML Engine Internals, Part 2: Bindings 译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/QML爱好 ...
- 深入解析QML引擎, 第3部分: 绑定类型
原文 QML Engine Internals, Part 3: Binding Types 译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/Q ...
- 深入解析QML引擎, 第1部分:QML文件加载
译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/QML爱好者和工作者也能更好的学习和理解QML引擎,故将这个系列的4篇文章翻译过来.翻译并不是完 ...
- 深度解析qml引擎---(2)绑定(binding)
强烈的希望是人生中比任何欢乐更大的兴奋剂.--尼采 上一篇文章讲了QML引擎加载qml文件的过程,大体过程是,解析qml文件,然后为文件中的每个元素创建对应的c++对象.例如,qml文件中如果使用了T ...
- 深度解析qml引擎---(1)Qml文件加载
"美的事物是永恒的喜悦" --- 济慈 ...
- cocos2d-x_下载游戏引擎并创建第一个项目
我是一名小白. 下载并创建游戏项目 第一步:去官网下载cocos2d-x http://www.cocos.com/download 第二步:将安装包里边的 setup.py 拖进命令行点击回车键 , ...
- QML和JS引擎的关系以及调用c++函数的原理
首先推荐几篇博客 1.深入解析QML引擎, 第1部分:QML文件加载 https://www.cnblogs.com/wzxNote/p/10569535.html 2.深入解析QML引擎, 第2部分 ...
- 使用QML创建第一个界面(转)
原文转自 https://blog.csdn.net/rl529014/article/details/51378307 在Qt编程中,我们可以使用纯C++代码,或C++和XML结合的方式来创建GUI ...
随机推荐
- 【学】AngularJS日记(3)- $apply(), run()方法
$scope.$apply()方法可以强制$apply()里运行的函数所改变的model里的数据直接反应到view里,因为在angular的环境中,有时会用到原生js或者jquery的时候,这些行为有 ...
- AOP的基本概念
1)aspect(切面):实现了cross-cutting功能,是针对切面的模块.最常见的是logging模块,这样,程序按功能被分为好几层,如果按传统的继承的话,商业模型继承日志模块的话根本没有什么 ...
- IOC框架整体介绍
1.Castle Windsor 2.Autofac 3.Unity 4.Spring.NET 5.StructureMap 6.Ninject
- UIButton的titleLabe setAttributeSting 首次不起作用
环境xcode7.3 ios9.3 真机模拟器均出现 UIButton的titleLabe setAttributeSting 首次不起作用,之后每一次 都正常,百思不得解,无奈之下改变策略,讲but ...
- lucene 内存索引 和文件索引 合并
IndexWriter.addIndexes(ramDirectory); http://blog.csdn.net/qq_28042463/article/details/51538283 在luc ...
- 整整十年 - Agent Framework for TypeScript 2.0
十年前,我发布了 Agent Framework for .NET 2.0 今天,Agent 又开始了新的旅程, 这次支持的语言是 TypeScript 2.0 上需求:init函数只能被调用一次 废 ...
- (2016 年) githup 博客地址 : https://github.com/JMWY/MyBlog
githup 博客地址 : https://github.com/JMWY/MyBlog
- SignalR 2.0 初次使用说明
如何使用SignalR 2.0 一:首先通过Nuget安装SignalR 2.0 [本人使用的时候最新版本为2.0]2.0与之前1.X有部分命名空间和配置不同请注意 二:建一个专门的类库用来负责Sig ...
- 好用的一个从SharePoint导出小工具
1. 输入 Site Url(Site Collection), 然后点"load"按钮 2.选择Web后,点选需导出的文档库,然后点"Next"按钮 ...
- ldap实现用户认证
LDAP的用户认证类. public class LDAPHelper { private DirectoryEntry _objDirectoryEntry; /// <summary> ...