oc/object-c/ios哪种遍历NSArray/NSDictionary方式快?测试报告
做app的时候,总免不了要多次遍历数组或者字典。
究竟哪种遍历方式比较快呢?我做了如下测试:
首先定义测试用宏:
| 
 
1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
#defineNSTimeIntervalNSLog(@"MULogTimeintervalBegin:%@",#definestartNSLog(@"%@:%f",duration#define | 
接着编写测试代码:
NSarray:
| 
 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
 | 
-void)testArray{    NSMutableArray*NSMutableArray    forNSInteger        [testArrayNSString"%ld",    }    NSLog(@"init:%ld",         __blockNSMutableString*NSMutableString         MULogTimeintervalBegin(@"ArrayTest");    NSUInteger    forNSInteger        [sum    }    [sum""];    MULogTimeintervalPauseAndLog(@"for);         for(NSString*        [sum    }    [sum""];    MULogTimeintervalPauseAndLog(@"for-in");         [testArrayidNSUIntegerBOOL        [sum    }];    [sum""];    MULogTimeintervalPauseAndLog(@"enumerateBlock");} | 
NSDictionary:
| 
 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
 | 
-void)testDictionary    NSMutableDictionary*NSMutableDictionary    forNSInteger        [testDic"test"NSString"%ld",    }    NSLog(@"init:%ld",         __blockNSMutableString*NSMutableString         MULogTimeintervalBegin(@"DictionaryTest");    forNSString*        [sum    }    [sum""];    MULogTimeintervalPauseAndLog(@"for);         forid        [sum    }    [sum""];    MULogTimeintervalPauseAndLog(@"for);         [testDicididBOOL        [sum    }    MULogTimeintervalPauseAndLog(@"enumeration");} | 
下面是测试结果:
Test Case '-[LoopTestTests testArray]' started.
2012-08-02 17:14:22.061 otest[388:303] init:100000
2012-08-02 17:14:22.062 otest[388:303] MULogTimeintervalBegin:ArrayTest
2012-08-02 17:14:22.075 otest[388:303]for statement:0.013108
2012-08-02 17:14:22.083 otest[388:303]for-in:0.008186
2012-08-02 17:14:22.095 otest[388:303] enumerateBlock:0.012290
Test Case '-[LoopTestTests testArray]' passed (0.165 seconds).
Test Case '-[LoopTestTests testDictionary]' started.
2012-08-02 17:14:22.273 otest[388:303] init:100000
2012-08-02 17:14:22.274 otest[388:303] MULogTimeintervalBegin:DictionaryTest
2012-08-02 17:14:22.284 otest[388:303] for statement allValues:0.010566
2012-08-02 17:14:22.307 otest[388:303] for statement allKeys:0.022377
2012-08-02 17:14:22.330 otest[388:303] enumeration:0.023914
Test Case '-[LoopTestTests testDictionary]' passed (0.217 seconds).
可以看出对于数组来说,for-in方式遍历速度是最快的,普通风格的for和block方式速度差不多。对于字典来说,allValues方式遍历最快,allKeys和block差不多。
那么,为什么会这样呢?
NSArray:
| 
 
1 
2 
3 
 | 
forNSInteger        [sum} | 
这里由于存在:[objectAtIndex:i]这样的取操作,所以速度会有所下降。
而
| 
 
1 
2 
3 
 | 
for(NSString*        [sum} | 
尽管也有取操作,但是绕开了oc的message机制,速度会快一点。也有可能是编译器为了for-in作了优化。
block为什么会慢一些这个有待研究。
NSDictionary:
| 
 
1 
2 
3 
 | 
forid        [sum} | 
这个就很明显了,第二种方法多了一次objectForKey的操作。block的话有待研究。
google了一下,stackoverflow上面有类似的讨论:点击打开链接
大意是:for-in语法会对容器里面的元素的内存地址建立一个缓冲,遍历的时候从缓冲直接取得元素的地址而不是通过调用方法来获取,所以效率比较高。另外,这也是不能在循环体中修改容器元素的原因之一。
												
											oc/object-c/ios哪种遍历NSArray/NSDictionary方式快?测试报告的更多相关文章
- iOS五种本地缓存数据方式
		
iOS五种本地缓存数据方式 iOS本地缓存数据方式有五种:前言 1.直接写文件方式:可以存储的对象有NSString.NSArray.NSDictionary.NSData.NSNumber,数据 ...
 - 遍历NSArray, NSDictionary, NSSet的方法总结
		
1,for循环读取 NSArray: NSArray *array = /*…*/ ; i<array.count; i++) { id object = array[i]; // do sth ...
 - HashMap两种遍历数据的方式
		
HashMap的遍历有两种方式,一种是entrySet的方式,另外一种是keySet的方式. 第一种利用entrySet的方式: Map map = new HashMap(); Iterator i ...
 - iOS - 数组与字典(NSArray & NSDictionary)
		
1. 数组的常用处理方式 //--------------------不可变数组 //1.数组的创建 NSString *s1 = @"zhangsan"; NSString *s ...
 - [集合]Map的 entrySet() 详解以及用法(四种遍历map的方式)
		
Entry 由于Map中存放的元素均为键值对,故每一个键值对必然存在一个映射关系. Map中采用Entry内部类来表示一个映射项,映射项包含Key和Value (我们总说键值对键值对, 每一个键值对也 ...
 - IOS四种保存数据的方式
		
在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题.将数据保存到本地,能够让程序的运行更加流畅,不会出现让人厌恶的菊花形状,使得用户体验更好.下面介绍一下数据保存的方式: 1.NSKeyed ...
 - IOS 四种保存数据的方式
		
在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题.将数据保存到本地,能够让程序的运行更加流畅,不会出现让人厌恶的菊花形状,使得用户体验更好.下面介绍一下数据保存的方式: 1.NSKeyed ...
 - Java中五种遍历HashMap的方式
		
import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class Java8Templat ...
 - 另一种遍历Map的方式: Map.Entry 和 Map.entrySet()
		
源网址: http://blog.csdn.net/mageshuai/article/details/3523116 今天看Think in java 的GUI这一章的时候,里面的TextArea这 ...
 
随机推荐
- u-boot中的Makefile
			
在windos下,pc机上电之后,BIOS会初始化硬件配置,为内核传递参数,引导操作系统启动,并且识别C盘.D盘.等整个操作系统启动起来之后,才可以运行应用程序比如QQ.QQ音影.同理,在嵌入式Lin ...
 - Linux系统调优及安全设置
			
1.关闭SELinux #临时关闭 setenforce 0 #永久关闭 vim /etc/selinux/config SELINUX=disabled 2.设定运行级别为3 #设定运行级别 vim ...
 - Linux 不常用命令总结
			
1. vim编辑模式下,搜索,/user,跳转下一个,小写的n 2.
 - Eloquent中一些其他的create方法
			
firstOrCreate/ firstOrNew# 还有两种其它方法,你可以用来通过属性批量赋值创建你的模型:firstOrCreate 和firstOrNew.firstOrCreate 方法将会 ...
 - CentOS系统yum源配置修改、yum安装软件包源码包出错解决办法apt.sw.be couldn't connect to host
			
yum安装包时报错: Could not retrieve mirrorlist http://mirrorlist.repoforge.org/el6/mirrors-rpmforge error ...
 - Java容器---Collection接口中的共有方法
			
1.Collection 接口 (1)Collection的超级接口是Iterable (2)Collection常用的子对象有:Map.List.Set.Queue. 右图中实现黑框的ArrayLi ...
 - 面试题13:在O(1)时间删除链表节点
			
注意分情况讨论: 1. 要删除的不是尾节点 2. 链表只有一个节点 3. 链表中有多个节点,删除尾节点 void DeleteNode(ListNode** pListHead, ListNode* ...
 - C# 使用UDP组播实现局域网桌面共享
			
最近需要在产品中加入桌面共享的功能,暂时不用实现远程控制:参考了园子里的一些文章,加入了一些自己的修改. 需求:将一台机器的桌面通过网络显示到多个客户端的屏幕上,显示内容可能为PPT,Word文档之类 ...
 - Gitlab基本管理(二)
			
一. Gitlab分支 1. 切换到项目位置. 2. 创建一个项目的一新分支. mike@win10-001 MINGW64 ~/cookbook/cookbook (master) $ git br ...
 - phpstorm配置关联php手册
			
最近发现有些编辑器可以 选中函数名,通过相应的快捷键就可以调用 浏览器 打开相应 函数的 在线帮助文档. 一番查找,我终于发现 phpStorm 也有相应的功能. 一.自带功能 在编辑器中选中函数名, ...