15

I have created a project on GitHub so I can learn how to optimize networking for my iOS apps. I have used blocks and GCD heavily and after watching WWDC 2012 videos and videos from past years I learned that I may be able to do more with NSOperationQueue. Specifically I can control the number of concurrent operations (network connections) as well as provide cancellation of operations. I am experimenting with allowing 1, 2, 4, 8 and 16 concurrent operations and I am seeing interesting results that I did not totally expect. I am measuring the results but I wonder if there is more that I should be measuring.

You can find sample project here:

https://github.com/brennanMKE/OptimizedNetworking

Since I am using the async API of NSURLConnection there is plenty of benefit to having many concurrent connections because the API spends a fair amount of time waiting for HTTP packets. Previously my code would start with an array of items to download and request them all sequentially, which is prevents the benefits of concurrency. I have also been using notifications to cancel network connections. Now I can do that with this project through operations and I have set them up to use a value for priority and a category so that I can prioritize and sort downloads and cancel a category of operations. I may choose to use a category for each view and when a user leaves a view all operations for that view will be cancelled using the category. This will free up resources for the active view.

One concern with using more concurrent operations is CPU usage as well as I/O, but I am not aware of a way to measure these values with iOS. The equivalent of the "w" command in iOS to show CPU usage could be useful. I am less concerned about I/O but measuring it would be more comprehensive.

My main issue with how I was doing networking was a responsive UI. I found that what I have been doing has made the UI sluggish. This new approach may help a great deal, but only if I keep the number of concurrent operations down. The optimal number of operations may vary by the type of connection (3G, WiFi, etc) so checking the connection type may lead to some optimizations.

If you are interested in better ways to speed up network communications in your app please try out this sample project and suggest other ways that I can measure performance and offer ways to further optimize communications. (Also note that I am referencing the Apple sample project MVCNetworking as well as the ASIHTTPRequest project.

What I may do next is to total up the amount of data downloaded and keep a log of that amount along with the total time to complete the download.

The README file should help explain the project and how it works.

Brennan
  • 11,546
  • 16
  • 64
  • 86
  • 1
    +1, effort, and interesting as well. – CodaFi Jul 18 '12 at 18:53
  • 1
    If you look at my project on github, NSOperation-WebFetches-MadeEasy, there is a helper class that manages the operations for you. I am using this exact code in two Apps in the store with great success, and I often add over 100 operations to the queue. Note that iOS works closely with NSOperationsQueue to manage load. I never see any affect on the main thread due. – David H Jul 18 '12 at 19:08
  • CodeFi Thanks. @DavidH I have forked your project and will look it over to see what I can learn from it. Thanks. – Brennan Jul 18 '12 at 20:02
  • OperationsRunner is the class. Essentially you add it to any class you want to manage operations. Its very small and only has a few methods you need to deal with. There are example NSConcurrent subclasses, a base class to build with and a WebFetcher, that are also small. – David H Jul 18 '12 at 21:21
  • Yes, I found the MVCNetworking example was far from a drop in solution. I am now seeing great numbers with using NSOperationQueue with 16 concurrent operations. – Brennan Jul 18 '12 at 21:35

1 Answers1

3

If this helps Mugunth Kumar actually checks the type of connection using the reachability class before setting the NSOperationQueue max connection size in the MKNetworkKit

IanStallings
  • 806
  • 10
  • 21
  • According the Quinn "the Eskimo" you should not base your networking on the type of connection (WiFi, 3G, Edge, etc) but should rather measure the speed of a download to decide. I am also interested in metrics for the iPod, iPhone and iPad for number of concurrent operations. I will check out MKNetworkKit. – Brennan Jul 25 '12 at 15:59
  • Although I do tend to agree I can see the advantage of knowing up front that we're on an EDGE network and the maximum download speed will probably only take 1-2 net operation queues at the maximum. Measuring the d/l speed could augment this first check possibly. If some assumption was incorrect we can make adjustments based on current throughput. – IanStallings Jul 25 '12 at 16:12
  • 1
    With my sample app I plan to track performance to show stats for the various scenarios. I will probably put together something Core Data to keep a running tally of results to allow for a summary of all history. That may reveal ways to optimize further. – Brennan Jul 26 '12 at 16:53
  • 1
    Speed affects download time. Type of connection affects the number of concurrent connections (mostly due to throttling by ISPs). After running a bunch of tests, I found that restricting the number of connections on a 3G network actually does more good than harm. – Mugunth Aug 13 '12 at 17:44