From 6d85cd9061a637d5eb210a405a09811e9a1d7648 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Fri, 31 Aug 2018 17:47:39 +0800 Subject: [PATCH 1/3] Decrease animated decode times when cache enable --- SDWebImage/SDAnimatedImageView.m | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/SDWebImage/SDAnimatedImageView.m b/SDWebImage/SDAnimatedImageView.m index 32db4476..0e6c52fd 100644 --- a/SDWebImage/SDAnimatedImageView.m +++ b/SDWebImage/SDAnimatedImageView.m @@ -639,7 +639,7 @@ static NSUInteger SDDeviceFreeMemory() { } else if (currentData.length > previousData.length) { // If current data is appended by previous data, use `NSDataSearchAnchored` NSRange range = [currentData rangeOfData:previousData options:NSDataSearchAnchored range:NSMakeRange(0, previousData.length)]; - if (range.location == 0 && range.length == previousData.length) { + if (range.location == 0) { // Contains hole previous data and they start with the same beginning self.isProgressive = YES; } @@ -743,13 +743,19 @@ static NSUInteger SDDeviceFreeMemory() { // Or, most cases, the decode speed is faster than render speed, we fetch next frame fetchFrameIndex = nextFrameIndex; } - if (!bufferFull && self.fetchQueue.operationCount == 0) { + + UIImage *fetchFrame; + LOCKBLOCK({ + fetchFrame = self.frameBuffer[@(fetchFrameIndex)]; + }); + + if (!fetchFrame && !bufferFull && self.fetchQueue.operationCount == 0) { // Prefetch next frame in background queue UIImage *animatedImage = self.animatedImage; NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ - UIImage *fetchFrame = [animatedImage animatedImageFrameAtIndex:fetchFrameIndex]; + UIImage *frame = [animatedImage animatedImageFrameAtIndex:fetchFrameIndex]; LOCKBLOCK({ - self.frameBuffer[@(fetchFrameIndex)] = fetchFrame; + self.frameBuffer[@(fetchFrameIndex)] = frame; }); }]; [self.fetchQueue addOperation:operation]; From 759b7322c972e72cc3571b9adeae4b6fb62200cd Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Fri, 31 Aug 2018 21:53:53 +0800 Subject: [PATCH 2/3] Remove lock tradeoff when get fetchFrame --- SDWebImage/SDAnimatedImageView.m | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/SDWebImage/SDAnimatedImageView.m b/SDWebImage/SDAnimatedImageView.m index 0e6c52fd..9c7d4595 100644 --- a/SDWebImage/SDAnimatedImageView.m +++ b/SDWebImage/SDAnimatedImageView.m @@ -689,8 +689,10 @@ static NSUInteger SDDeviceFreeMemory() { // Update the current frame UIImage *currentFrame; + UIImage *fetchFrame; LOCKBLOCK({ currentFrame = self.frameBuffer[@(currentFrameIndex)]; + fetchFrame = currentFrame ? self.frameBuffer[@(nextFrameIndex)] : nil; }); BOOL bufferFull = NO; if (currentFrame) { @@ -744,11 +746,6 @@ static NSUInteger SDDeviceFreeMemory() { fetchFrameIndex = nextFrameIndex; } - UIImage *fetchFrame; - LOCKBLOCK({ - fetchFrame = self.frameBuffer[@(fetchFrameIndex)]; - }); - if (!fetchFrame && !bufferFull && self.fetchQueue.operationCount == 0) { // Prefetch next frame in background queue UIImage *animatedImage = self.animatedImage; From 3dc5b0ab67e10d7d8c5be3f406598c6188ef46bb Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Mon, 3 Sep 2018 16:34:17 +0800 Subject: [PATCH 3/3] Change data compare statement when do animated data comparation --- SDWebImage/SDAnimatedImageView.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SDWebImage/SDAnimatedImageView.m b/SDWebImage/SDAnimatedImageView.m index 9c7d4595..b858aef6 100644 --- a/SDWebImage/SDAnimatedImageView.m +++ b/SDWebImage/SDAnimatedImageView.m @@ -637,9 +637,9 @@ static NSUInteger SDDeviceFreeMemory() { // If current data is the same data (or instance) as previous data self.isProgressive = YES; } else if (currentData.length > previousData.length) { - // If current data is appended by previous data, use `NSDataSearchAnchored` + // If current data is appended by previous data, use `NSDataSearchAnchored`, search is limited to start of currentData NSRange range = [currentData rangeOfData:previousData options:NSDataSearchAnchored range:NSMakeRange(0, previousData.length)]; - if (range.location == 0) { + if (range.location != NSNotFound) { // Contains hole previous data and they start with the same beginning self.isProgressive = YES; }