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.

 

詳細的了解提升文件操作性能的方法,請參考以下文章:

File System Programming Guide

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 or FSSpec 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連接等),用得不多,做網絡使用狀況分析時用用還行。

 

 

 

參考:

淺談無緩存I/O操作和標准I/O文件操作區別

File System Programming Guide

基本文件操作:NSFileHandle的用法

iOS開發-多線程編程技術

iOS文件操作(IO)的Benchmark

iOS App性能優化

 

引用請注明出處:http://www.cnblogs.com/JuneWang/p/4864225.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM