Rich
Rich

Reputation: 121

NSURLSessionDataTask causes high CPU usage

I'm using a NSURLSessionDataTask to feed data into an audio stream in the background (not really relevant in this case).

The problem I'm encountering happens with just the downloading code - I've isolated this and simply discard the data, so no other parts of the system are affecting it.

I've observed that if I create the NSURLSession with a config (NSURLSessionConfiguration) created using backgroundSessionConfigurationWithIdentifier then the CPU usage while downloading is low (<5%). Although this works (95% of the time), I believe it's not a supported configuration. I also only need this to work when the app is in the foreground.

So, instead, I create the NSURLSession with a config created using ephemeralSessionConfiguration, this also stops it using the disk as a background cache and should therefore use the least CPU. However, in this scenario CPU usage rockets to between 70% & 80%.

The same high CPU usage also occurs with config created using defaultSessionConfiguration or even getting the shared NSURLSession using [NSURLSession sharedSession].

The data throughput is unchanged between each scenario - just not running in the background causes high CPU usage.

I'm running on iOS 9.1 using SDK 9.1. It happens in both the simulator and on-device.

Update 16th Nov - As George pointed out, it appears then the didReceiveData method is thrashed. The only way I've found to deal with this is to add in a call to

[NSThread sleepForTimeInterval:0.25];

which seems pretty drastic, but takes the CPU from around 60-80% when downloading, to around 10-12%. The download is running in it's own thread, so it's only the download that is slowed down. In fact, it's not really slowed down - the didReceiveData just receives data in much larger chunks. In my app this doesn't matter.

Upvotes: 4

Views: 1703

Answers (1)

Charles A.
Charles A.

Reputation: 11123

You should probably set the delegateQueue of the NSURLSession to be a low priority queue (i.e., dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0). I assume the problem is not that processing actually takes more CPU, but that it happens more frequently because the queue it is dispatching to is high priority.

Upvotes: 1

Related Questions