Vector效率

简介: 自FlashPlayer10伴随着FlashCS4发布时,AS3中就多了一种新的数据类型:Vector这里先给不大熟悉Vector的同学们做一下简介(节选并改编自官方文档): Vector是一种特殊的数组首先,Vector的定义和C语言中“数组”更为接近,即数组的每一个元素都有相同的数据类型。

自FlashPlayer10伴随着FlashCS4发布时,AS3中就多了一种新的数据类型:Vector
这里先给不大熟悉Vector的同学们做一下简介(节选并改编自官方文档):

Vector是一种特殊的数组
首先,Vector的定义和C语言中“数组”更为接近,即数组的每一个元素都有相同的数据类型。(这就意味着对Vector中元素的访问要经过类型检查)
其次,Vector是一种密集数组,即每一个索引中必须包含一个值。(可以是null)
最后,Vector可以随时指定为固定长度的数组。

由于这些特殊性,Vector便拥有以下几点优势:
性能:使用 Vector 实例时的组元素的访问和迭代速度比使用 Array 时的要快很多。
类型安全性:在严格模式下,编译器可以识别数据类型错误。(但当使用 push() 方法或 unshift() 方法向 Vector 添加值时,编译器不会检查参数的数据类型,而是在运行时检查)
可靠性:相对于 Array,运行时范围检查(或定长检查)极大地提高了可靠性。

今天我们主要关注的是使用Vector数据类型来优化程序效率。
对于追求效率的RIA应用,使用Vector来提升效率是一种简单却行之有效的办法,
然而很多开发者对Vector的了解不够深入,以致未能充分发挥Vector在速度的优势。
接下来我们便来剖析一下Vector的最佳使用方法。

注:下文中所有代码的运行环境:FlashPlayer 10.1 & Mac OS X 10.6.4,所有耗时均经过多次统计平均并取整。一、Vector数组的长度应当固定
Vector类型在AVM中的实现使用的是定长数组,虽然在AS3中其fixed属性默认为false,但仍不建议对Vector数组进行能够更改长度的操作。
请看以下测试:?

01 var a:Vector.=new Vector.(1000000);
02 var b:Vector.=new Vector.(10000000);
03 var t:Number=getTimer();
04 for(var k:uint=0;k<9;k+=1){
05 a.concat(new Vector.(1000000));
06 }
07 for(var i:uint=0;i<10000000;i+=1){
08 a[i]=i;
09 i=a[i];
10 }
11 trace(getTimer()-t);
12 //////////////////////////////////
13 t=getTimer();
14 for(var j:uint=0;j<10000000;j+=1){
15 b[j]=j;
16 j=b[j];
17 }
18 trace(getTimer()-t);

同样是对长度为1千万的数组进行操作,前者的耗时在850ms,后者则保持在350ms。
如果将上述代码中的Vector a使用1千万次push操作来达到1千万的长度,则耗时变为1800ms。
(事实上,用上述代码对Array进行测试,有同样的耗时比率,所以无论使用哪种数组,都不建议频繁改变其长度)
至于splice操作的耗时,请参见gskinner的Quick As A Flash: Optimization Strategies for AS3 and Flash可以看到,Vector的splice操作要比Array慢出10倍。二、正向/逆向遍历的速度无差异
对于Array类型,正向/逆向遍历其元素的速度大约是3:2,即逆向遍历要慢一些,比如以下代码:?

1 var a:Array=new Array(10000000);
2 var b:Array=new Array(10000000);
3 var t:Number=getTimer();
4 for(var i:uint=0;i<10000000;i+=1){ a[i]=i; i=a[i]; } trace(getTimer()-t); ////////////////////////////////// t=getTimer(); for(var j:uint=9999999;j>0;j-=1){
5 b[j]=j;
6 j=b[j];
7 }
8 trace(getTimer()-t);

前者的耗时约是1000ms,后者则是1500ms。
而对于Vector,这种正向/逆向间的速度差异不存在。(有兴趣可以自行修改上面代码进行测试,此处作为结论给出)三、使用Vector储存基元类型的数据时,才能充分发挥Vector的效率优势
AS3内的数据类型分为基元类型和引用类型两种,对于这两种不同类型的数据,使用Vector的效率也是不同的。(需要指出的是,这两种类型在AS3中本质都是引用类型,只不过前者是不变对象,后者是可变对象)
首先是储存基元类型数据时,Vector与Array的读写效率对比:?

01 var a:Vector.=new Vector.(10000000);
02 var b:Array=new Array(10000000);
03 var t:Number=getTimer();
04 for(var i:uint=0;i<10000000;i+=1){
05 a[i]=i;
06 i=a[i];
07 }
08 trace(getTimer()-t);
09 //////////////////////////////////
10 t=getTimer();
11 for(var j:uint=0;j<10000000;j+=1){
12 b[j]=j;
13 j=b[j];
14 }
15 trace(getTimer()-t);

使用Vector耗时在400ms左右,而使用Array则是1200ms。
可见在使用基元类型时,Vector的访问速度相比Array有三倍(以上)的优势。
接下来看看储存引用类型数据时的效率对比:
二者的耗时基本一样,经过多次平均,Array耗时要比Vector多3%~8%,速度上仍然不及Vector,如非对效率要求极高,基本可以忽略。
最后对使用String类型的情况进行了单独测试,与引用类型下的表现结果一致。
四、注意索引的数据类型
很多开发者会忽略一个细节,那就是在AS3中“看起来是整数的”不一定就是整数类型。
请看以下的代码段:

01 var a:Vector.=new Vector.(10000000);
02 var t:Number=getTimer();
03 for(var i:uint=0;i<10000000;i+=1){
04 a[i*2/2]=i;
05 i=a[i*2/2];
06 }
07 trace(getTimer()-t);
08 //////////////////////////////////
09 t=getTimer();
10 for(var j:uint=0;j<10000000;j+=1){
11 a[uint(j*2/2)]=j;
12 j=a[uint(j*2/2)];
13 }
14 trace(getTimer()-t);
15 //////////////////////////////////
16 t=getTimer();
17 for(var k:uint=0;k<10000000;k+=1){ a[(k*2/2)>>0]=k;
18 k=a[(k*2/2)>>0];
19 }
20 trace(getTimer()-t);
21 //////////////////////////////////
22 t=getTimer();
23 var n:uint;
24 for(var q:uint=0;q<10000000;q+=1){
25 n=(q*2/2);
26 a[n]=q;
27 q=a[n];
28 }
29 trace(getTimer()-t);

四种方式的耗时分别是1100ms,750ms,650ms,550ms,当然,最后一种由于只计算了一次,不具可比性。(如果同样计算两次,则是750ms)
这里测试用的是乘法和除法,另经测试,+1/-1的结果也是一样。
所以这里特地提一下,如果一定要把算式直接写在索引的位置,要使用位运算将其转化为整数。
关于AS3效率优化中Vector的使用,目前我能想到的就是这四点。(不排除以后想起来了再更新)
希望能对各位有所帮助。

相关文章
|
传感器 监控 BI
基于STM32的智能垃圾分类系统设计与实现
基于STM32的智能垃圾分类系统设计与实现
1035 0
|
9月前
|
人工智能 搜索推荐 Docker
手把手教你使用 Ollama 和 LobeChat 快速本地部署 DeepSeek R1 模型,创建个性化 AI 助手
DeepSeek R1 + LobeChat + Ollama:快速本地部署模型,创建个性化 AI 助手
6109 119
手把手教你使用 Ollama 和 LobeChat 快速本地部署 DeepSeek R1 模型,创建个性化 AI 助手
|
11月前
|
数据采集 人工智能 编解码
书生·万象InternVL 2.5:上海 AI Lab 开源的多模态大语言模型,超越了目前许多商业模型
书生·万象InternVL 2.5是由上海AI实验室OpenGVLab团队推出的开源多模态大语言模型系列。该模型在多模态理解基准(MMMU)上表现优异,超越了许多商业模型,适用于图像和视频分析、视觉问答、文档理解和多语言处理等多个领域。
967 7
书生·万象InternVL 2.5:上海 AI Lab 开源的多模态大语言模型,超越了目前许多商业模型
|
11月前
|
Linux Shell
Linux 10 个“who”命令示例
Linux 10 个“who”命令示例
277 14
Linux 10 个“who”命令示例
|
11月前
|
JSON 缓存 前端开发
HarmonyOS NEXT 5.0鸿蒙开发一套影院APP(附带源码)
本项目基于HarmonyOS NEXT 5.0开发了一款影院应用程序,主要实现了电影和影院信息的展示功能。应用包括首页、电影列表、影院列表等模块。首页包含轮播图与正在热映及即将上映的电影切换显示;电影列表模块通过API获取电影数据并以网格形式展示,用户可以查看电影详情;影院列表则允许用户选择城市后查看对应影院信息,并支持城市选择弹窗。此外,项目中还集成了Axios用于网络请求,并进行了二次封装以简化接口调用流程,同时添加了请求和响应拦截器来处理通用逻辑。整体代码结构清晰,使用了组件化开发方式,便于维护和扩展。 该简介概括了提供的内容,但请注意实际开发中还需考虑UI优化、性能提升等方面的工作。
420 11
|
监控 安全 Apache
Apache ZooKeeper - 使用ZK实现分布式锁(非公平锁/公平锁/共享锁 )
Apache ZooKeeper - 使用ZK实现分布式锁(非公平锁/公平锁/共享锁 )
773 1
|
存储 JSON 数据格式
Python教程:json中load和loads的区别
【7月更文挑战第17天】在Python的`json`模块中, `load`与`loads`函数均用于JSON至Python对象的转换, 区别在于: - **`loads`**处理JSON格式的**字符串** 其中`data.json`文件内容为`{&quot;name&quot;: &quot;Bob&quot;, &quot;age&quot;: 30}`。 简而言之, `loads`用于字符串, 而`load`用于文件对象。根据数据来源选择合适的方法。
483 5
|
人工智能 自然语言处理 NoSQL
Transformers 4.37 中文文档(四十九)(1)
Transformers 4.37 中文文档(四十九)
246 2
|
机器学习/深度学习 算法 数据挖掘
操作系统调度算法的演进与性能分析
随着计算机科学的发展,操作系统作为硬件与软件之间的桥梁,其调度算法对系统性能有着举足轻重的影响。本文将探讨操作系统中调度算法的演变,从早期的简单调度策略到现代复杂的多级反馈队列和实时调度机制,并结合最新研究和实验数据,深入分析不同调度算法对系统吞吐量、响应时间及资源利用率的影响。通过对调度算法性能的定量评估,本文旨在为系统设计者提供优化决策的理论依据,同时为未来调度算法的研究指明方向。
211 0
|
安全 Android开发 开发者
安卓手机系统的优势和劣势分析
【2月更文挑战第8天】 安卓(Android)是目前全球最流行的移动操作系统之一,拥有强大的开源技术和丰富的应用生态系统。本文将从多个维度对安卓系统进行分析,并探讨其优势和劣势。
1929 2