From 6406d8e526c3c19878a490aac3056dad5b5faf74 Mon Sep 17 00:00:00 2001 From: Harish Krishnamurthy Date: Wed, 21 Jan 2015 13:27:18 -0500 Subject: [PATCH 1/3] Modifies SDWebImagePrefetcher prefetching logic. - Removes recursive calls to startPrefetchingAtIndex. - Uses dispatch_apply with striding to optimize the performance. --- SDWebImage/SDWebImagePrefetcher.m | 32 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/SDWebImage/SDWebImagePrefetcher.m b/SDWebImage/SDWebImagePrefetcher.m index 7942120..108f127 100644 --- a/SDWebImage/SDWebImagePrefetcher.m +++ b/SDWebImage/SDWebImagePrefetcher.m @@ -78,12 +78,7 @@ didPrefetchURL:self.prefetchURLs[index] finishedCount:self.finishedCount totalCount:self.prefetchURLs.count - ]; - } - if (self.prefetchURLs.count > self.requestedCount) { - dispatch_async(self.prefetcherQueue, ^{ - [self startPrefetchingAtIndex:self.requestedCount]; - }); + ]; } else if (self.finishedCount == self.requestedCount) { [self reportStatus]; @@ -102,7 +97,7 @@ [self.delegate imagePrefetcher:self didFinishWithTotalCount:(total - self.skippedCount) skippedCount:self.skippedCount - ]; + ]; } } @@ -117,14 +112,29 @@ self.completionBlock = completionBlock; self.progressBlock = progressBlock; - if(urls.count == 0){ + __weak SDWebImagePrefetcher *weakSelf = self; + + if(urls.count == 0){ if(completionBlock){ completionBlock(0,0); } }else{ - // Starts prefetching from the very first image on the list with the max allowed concurrency - NSUInteger listCount = self.prefetchURLs.count; - for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) { + // http://oleb.net/blog/2013/07/parallelize-for-loops-gcd-dispatch_apply/ + // Optimize the maxConcurrentdownloads for effeciency. Since caching operations are involved that are non-trivial using + // dispatch_apply might be helpful. + + NSInteger maxNumberOfImages = self.prefetchURLs.count; + + dispatch_apply(maxNumberOfImages/self.maxConcurrentDownloads, dispatch_get_global_queue(self.prefetcherQueue, 0), ^(size_t index) { + size_t i = index * self.maxConcurrentDownloads; + size_t stop = i + self.maxConcurrentDownloads; + do{ + [weakSelf startPrefetchingAtIndex:i++]; + }while (i < stop); + }); + + // Download remaining images. + for (size_t i = maxNumberOfImages - (maxNumberOfImages % self.maxConcurrentDownloads); i < (size_t)maxNumberOfImages; i++) { [self startPrefetchingAtIndex:i]; } } From ac9889609996ddbbf375e62dc743bb7dac17be57 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sun, 25 Oct 2015 19:32:31 +0200 Subject: [PATCH 2/3] Code style --- SDWebImage/SDWebImagePrefetcher.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/SDWebImage/SDWebImagePrefetcher.m b/SDWebImage/SDWebImagePrefetcher.m index 108f127..7447a86 100644 --- a/SDWebImage/SDWebImagePrefetcher.m +++ b/SDWebImage/SDWebImagePrefetcher.m @@ -114,11 +114,11 @@ __weak SDWebImagePrefetcher *weakSelf = self; - if(urls.count == 0){ - if(completionBlock){ + if (urls.count == 0) { + if (completionBlock) { completionBlock(0,0); } - }else{ + } else { // http://oleb.net/blog/2013/07/parallelize-for-loops-gcd-dispatch_apply/ // Optimize the maxConcurrentdownloads for effeciency. Since caching operations are involved that are non-trivial using // dispatch_apply might be helpful. @@ -128,9 +128,9 @@ dispatch_apply(maxNumberOfImages/self.maxConcurrentDownloads, dispatch_get_global_queue(self.prefetcherQueue, 0), ^(size_t index) { size_t i = index * self.maxConcurrentDownloads; size_t stop = i + self.maxConcurrentDownloads; - do{ + do { [weakSelf startPrefetchingAtIndex:i++]; - }while (i < stop); + } while (i < stop); }); // Download remaining images. From 04a0431ae914fd5ea871725edc5af4e0b981ae24 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sun, 25 Oct 2015 19:35:26 +0200 Subject: [PATCH 3/3] Making sure all access to self.runningOperations is synchronized --- SDWebImage/SDWebImageManager.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index 319d847..6ca4713 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -301,7 +301,11 @@ } - (BOOL)isRunning { - return self.runningOperations.count > 0; + BOOL isRunning = NO; + @synchronized(self.runningOperations) { + isRunning = (self.runningOperations.count > 0); + } + return isRunning; } @end