iOS的I/O操作
一般而言,处理文件时都要经历以下四个步骤:
1.创建文件
2.打开文件,以便在后面的I/O操作中引用该文件
3.对打开的文件执行I/O操作(读取、写入、更新)
4.关闭文件
iOS中,对文件常见的处理方式详解(通过该文章,我们可以了解在iOS中,常用的文件处理方法)
iOS开发之沙盒和文件操作(iOS的沙盒机制,应用只能访问自己应用目录下的文件)
在APP中,因为文件的I/O操作和网络操作一般来说需要耗费很长时间,如果放在主线程中进行,容易阻塞主线程(卡顿、点击不起作用等)
iOS性能优化系列三:事件处理-拯救主线程(通过最小化主线程CPU占用、将工作搬离主线程、不要阻塞主线程等方法,避免卡顿等出现)
下面将详细讲解iOS中多线程的相关概念:
1. 进程:进程(process):是指在系统中正在独立运行的一个应用程序. 比如同时打开QQ, Xcode,系统就会分别启动两个进程 (一个比较生动的讲解进程、线程的文章)
2. 线程:线程(thread):是程序的一段执行序列,是进程的一部分
2.1 线程的特点:
a.每一个进程都至少要有一个线程,可以有多个线程
b.适当数量线程能够提高程序的运行效率
2.2 线程越多越好吗?
a. iOS中主线程占用1M,子线程占用512KB
b. 程序设计更加复杂
3. 多线程: 一个进程中同时运行多个线程,称为多线程并发
多线程在iOS中的应用
3.1 一个ios程序启动的时候,默认会开启一个线程,该线程就是主线程
3.2 主线程作用:显示/刷新UI界面;处理UI事件(点击事件、拖拽事件、滚动事件等)
4.iOS多线程编程技术(iOS开发-多线程编程技术)(可以通过Thread、Cocoa operations、GCD等方式,创建新的线程,用来处理网络、文件I/O等其他操作,避免阻塞主线程)
因为将文件读写入硬盘是非常耗费时间的,可以通过缓冲的方式,减少文件读写硬盘的次数,节省时间,提升性能。
buffer(缓冲)是为了提高内存和硬盘(或其他I/0设备)之间的数据交换的速度而设计的。位于内存中
cache(缓存)是为了提高cpu和内存之间的数据交换速度而设计,也就是平常见到的一级缓存、二级缓存、三级缓存。是位于CPU与主内存间的一种容量较小但速度很高的存储器。
由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,为了提高CPU和内存之间数据交换的速度,在CPU和内存之间增加了Cache。因为某一段时间内,CPU执行的指令和访问的数据往往在集中的某一块,将这一块数据保存在Cache中,当CPU再次使用该部分数据时可从Cache中直接调用,这样就减少了CPU的等待时间,提高了系统的效率。
缓冲(buffers)是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。通过缓冲区,可以使进程之间的相互等待变少,从而使从速度慢的设备读入数据时,速度快的设备的操作进程不发生间断。
通过参考iOS文件操作(IO)的Benchmark文章所做的实验,可以看出缓存对性能的影响,以及如果设置不同大小缓冲区对性能的影响。
结果如下:
1)写文件:
API:
- (void)writeData:(NSData *)data;
- (void)synchronizeFile;
Benchmark结果
写入数据:512KB/次 次数:2000次 总大小:1GB 耗时:15.400s ~ 15.800s(最后Syn) / 29.600s ~ 30.000s(每次Syn)
写入数据:1MB/次 次数:1000次 总大小:1GB 耗时:15.400s ~ 15.800s(最后Syn) / 24.400s ~ 25.200s(每次Syn)
写入数据:2MB/次 次数:500次 总大小:1GB 耗时:15.400s ~ 15.800s(最后Syn) / 21.400s ~ 21.800s(每次Syn)
写入数据:4MB/次 次数:250次 总大小:1GB 耗时:15.400s ~ 15.800s(最后Syn) / 20.500s ~ 20.800s(每次Syn)
写入数据:8MB/次 次数:125次 总大小:1GB 耗时:15.400s ~ 15.800s(最后Syn) / 20.300s ~ 20.600s(每次Syn)
ps:Syn表示调用synchronizeFile来flush缓存 从上面的Benchmark可以看到,对于一定量的数据来说,缓冲区到硬盘的IO操作是由系统控制的,因此只在最后Syn的情况下,各种大小的字节数据writeData写入缓冲区使用的时间几乎是一样的,而每次writeData之后立刻调用Syn,则会让IO的操作增加,导致耗时的增加。所以,假如数据是可恢复的,那建议在写完数据所有数据之后再调用Syn。IO的写入效率为65M/s左右。
2)读文件:
API:
- (NSData *)readDataToEndOfFile; - (NSData *)readDataOfLength:(NSUInteger)length;
Benchmark结果
读取数据:1KB/次 次数:10242次 总大小:1GB 耗时:32.200s ~ 32.500s
读取数据:126KB/次 次数:4096次 总大小:1GB 耗时:11.100s ~ 11.300s
读取数据:256KB/次 次数:4096次 总大小:1GB 耗时:10.800s ~ 11.000s
读取数据:512KB/次 次数:2048次 总大小:1GB 耗时:10.300s ~ 10.600s
读取数据:1MB/次 次数:1024次 总大小:1GB 耗时:10.600s ~ 10.800s
读取数据:2MB/次 次数:512次 总大小:1GB 耗时:10.600s ~ 10.800s
读取数据:4MB/次 次数:256次 总大小:1GB 耗时:10.600s ~ 10.800s
读取数据:8MB/次 次数:128次 总大小:1GB 耗时:10.000s ~ 10.200s
从上面的benchmark发现,读512KB到8M各种大小规格数据块,效率上差别不大(相对于IO,遍历2000次与125次的差别微乎其微,因此忽略),但可看到从256KB逐步减小每次读取的数据块开始,耗时开始增加,当每次读取1KB的时候,耗时拉长到3倍,原因是没有充分利用IO缓冲区,增加了IO操作次数导致的;在现有的系统环境下,单次读取数据再继续往上测试的意义不大(单次读取16M、32M占用内存过大)。由测试得出,在现有测试环境下,每次读取数据块合理大小为512KB~4MB,IO读取效率为 100M/s 左右。
引自Apple 文档:https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/PerformanceTips/PerformanceTips.html Choose an appropriate read buffer size. When reading data from the disk to a local buffer, the buffer size you choose can have a dramatic effect on the speed of the operation. If you are working with relatively large files, it does not make sense to allocate a 1K buffer to read and process the data in small chunks. Instead, create a larger buffer (say 128K to 256K in size) and read much or all of the data into memory before processing it. The same rules apply for writing data to the disk: write data as sequentially as you can using a single file-system call.
详细的了解提升文件操作性能的方法,请参考以下文章:
Things to Look For in Your Code
If you are not sure where to start looking for potential fixes to your file-related code, here are some tips on where to start looking.
Look for places where your code is reading lots of files (of any type) from disk. Remember to look for places where you are loading resource files too. Are you actually using the data from all of those files right away? If not, you might want to load some of the files more lazily.
Look for places where you are using older file-system calls. Most of your calls should be using Objective-C interfaces or block-based interfaces. You can use BSD-level calls too but should not use older Carbon-based functions that operate on
FSRef
orFSSpec
data structures. Xcode generates warnings when it detects your code using deprecated methods and functions, so make sure you check those warnings.Look for places where you are using callback functions or methods to process file data. If a newer API is available that takes a block object, you might want to update your code to use that API instead.(避免使用主线程)
Look for places where you are performing many small read or write operations on the same file. Can you group those operations together and perform them all at once? For the same amount of data, one large read or write operation is usually more efficient than many small operations.(设置缓冲区)
备注:
文件和网络I/O
如果需要对app的文件和网络I/O情况做分析,可以用到这三个Instruments工具System Usage、File Activity和Network。
工具System Usage可以统计出运行状态下应用的文件和网络IO操作数据。例如我们发现应用启动后又一个峰值,这可能存在问题,我们可以利用System Usage工具的详细信息栏查看应用是由于对哪些文件的读写操作导致了峰值。
工具File Activity只能在模拟器中运行,因此数据采集可能不是非常准确。它同样可以详细给出读取的文件属性、大小、载入时间等信息,适合与System Usage配合使用。
Network工具则可以采集到应用的TCP/IP和UDP的使用信息(传输的数据量、当前所有TCP连接等),用得不多,做网络使用状况分析时用用还行。
参考:
引用请注明出处:http://www.cnblogs.com/JuneWang/p/4864225.html
iOS的I/O操作的更多相关文章
- iOS sqlite 的各种操作
iOS --SQL的增加.删除.查找.修改 iOS对于数据库的操作:增加.删除.查找.修改 首先需要创建一个数据库:本程序的数据库是在火狐浏览器里的插件里写的微量型数据库 火狐找查找SQLite Ma ...
- iOS 检查app版本更新操作
iOS 检查app版本更新操作 1:获取本地安装的版本信息: [NSString stringWithFormat:@"Version %@ (%@)", [[[NSBundle ...
- 在Visual Studio 2013/2015上使用C#开发Android/IOS安装包和操作步骤
Xamarin 配置手册和离线包下载 http://pan.baidu.com/s/1eQ3qw8a 具体操作: 安装前提条件 1. 安装Visual Studio 2013,安装过程省略,我这里安装 ...
- iOS抓包Charles 操作
今天就来看一下Mac上如何进行抓包,之前有一篇文章介绍了使用Fidder进行抓包 http://blog.csdn.net/jiangwei0910410003/article/details/198 ...
- IOS异步和多线程操作&&在sqlite3中的应用
1,数据库I/O操作(异步) 数据库本身是存储在磁盘上.访问和修改数据库,即对磁盘进行读写,即I/O操作. 磁盘属于计算机硬件,具有DMA能力,不需要CPU干预,可以实现异步操作. I/O操作一般是消 ...
- 关于ios中的文本操作-简介
来源:About Text Handling in iOS 官方文档 iOS平台为我们提供了许多在app中展示文本和让用户编辑文本的方式.同时,它也允许你在app视图中展示格式化的文本和网页内容.你可 ...
- iOS 中SQLite数据库操作
在iOS中实现SQLite数据库的操作:1.导入框架(libsqlite3.0.tbd) 2.导入头文件<sqlite3.h> 3.实现数据的增删改查 实现简单 SQLite数据库操作 的 ...
- QF——iOS中的数据库操作:SQLite数据库,第三方封装库FMDB,CoreData
SQLite数据库: SQLite是轻量级的数据库,适合应用在移动设备和小型设备上,它的优点是轻量,可移植性强.但它的缺点是它的API是用C写的,不是面向对象的.整体来说,操作起来比较麻烦.所以,一般 ...
- iOS UITableView左滑操作功能的实现(iOS8-11)
WeTest 导读 本文主要是介绍下iOS 11系统及iOS 11之前的系统在实现左滑操作功能上的区别,及如何自定义左滑的标题颜色.字体大小. 一.左滑操作功能实现 1.如果左滑的时候只有一个操作按钮 ...
随机推荐
- PL/0编译器(java version)–Pcode.java
1: package compiler; 2: 3: /** 4: * //虚拟机指令 5: * 6: * @author jiangnan 7: * 8: */ 9: public class ...
- 初学structs2,表单验证简单补充
一.使用注解方式,跳过验证某个方法 由于在开发中,我们不需在请求每一个action类中的方法时都要走validate方法,那么我们可以在这些不需要验证的方法上加上@SkipValidation注解即可 ...
- 远程桌面连接不上|windows server 2003 sp2 termdd.sys(转载)
远程桌面连接不上|windows server 2003 sp2 termdd.sys.请教一个问题,为什么 Windows Server 2003 打上SP2补丁,就不能通过远程桌面连接上去了?服务 ...
- eq相等 ne、neq不相等, gt大于, lt小于 gte、ge大于等于 lte、le 小于等于 not非 mod求模 等
eq相等 ne.neq不相等, gt大于, lt小于 gte.ge大于等于 lte.le 小于等于 not非 mod求模 is [not] div by是否能被某数整除 i ...
- Swift翻译之-Swift语法入门 Swift语法介绍
目录[-] Hello world - Swift 简单赋值 控制流 函数与闭包 对象和类 枚举与结构 协议和扩展 泛型 2014.6.3日,苹果公布最新编程语言Swift,Swift是一种新的编程语 ...
- (转)MFC中获得各个类的指针/句柄 ID的总结
http://www.cnblogs.com/ylhome/archive/2009/10/06/1578478.html 一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard ...
- 字符串数组元素排列与组合的Java递归实现
我们在笔试面试过程中经常会遇到关于排列与组合的问题,其实这些可以通过递归简单的实现,看下面两个例子: (1)关于字符串排列的问题 输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串ab ...
- 3DES封装类
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Se ...
- 并发包之Future:代码级控制超时时间
先谢Doug Lea. 使用场景: 最近在做webservice调用的时候,发现一个问题,对方的webservice接口很不稳定,所以在获取的数据时候经常要等待很久才能把数据全部拉回来,甚至有时候直接 ...
- ubuntu打不开图形界面,显示run in low_graphic mode
我上次因为这个问题重装了ubuntu,结果没两天又有问题了,这次我看到了未重启前的提示,说我的硬盘空间剩0kb,所以我心有余悸的想办法留空间,十分担心会有上次的问题出现,为了验证我的想法,我重启了一下 ...