Permalink
Browse files

Reduce contention by releasing lock before writing metadata to disk.

  • Loading branch information...
1 parent 2fa3aec commit f7114965d0be9472e05d89c49e669080bea7ffe6 Mallory Paine committed Feb 15, 2014
Showing with 19 additions and 13 deletions.
  1. +19 −13 FastImageCache/FICImageTable.m
@@ -595,21 +595,27 @@ - (NSNumber *)_numberForEntryAtIndex:(NSInteger)index {
- (void)saveMetadata {
[_lock lock];
- NSArray *mruArray = [_MRUEntries array];
NSDictionary *metadataDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
- _indexMap, FICImageTableIndexMapKey,
- _sourceImageMap, FICImageTableContextMapKey,
- mruArray, FICImageTableMRUArrayKey,
- _imageFormatDictionary, FICImageTableFormatKey, nil];
-
- NSData *data = [NSPropertyListSerialization dataWithPropertyList:metadataDictionary format:NSPropertyListBinaryFormat_v1_0 options:0 error:NULL];
- BOOL fileWriteResult = [data writeToFile:[self metadataFilePath] atomically:NO];
- if (fileWriteResult == NO) {
- NSString *message = [NSString stringWithFormat:@"*** FIC Error: %s couldn't write metadata for format %@", __PRETTY_FUNCTION__, [_imageFormat name]];
- [[FICImageCache sharedImageCache] _logMessage:message];
- }
-
+ [_indexMap copy], FICImageTableIndexMapKey,
+ [_sourceImageMap copy], FICImageTableContextMapKey,
+ [[_MRUEntries array] copy], FICImageTableMRUArrayKey,
+ [_imageFormatDictionary copy], FICImageTableFormatKey, nil];
[_lock unlock];
+
+ static dispatch_queue_t __metadataQueue = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ __metadataQueue = dispatch_queue_create("com.path.FastImageCache.ImageTableMetadataQueue", NULL);
+ });
+
+ dispatch_async(__metadataQueue, ^{
+ NSData *data = [NSPropertyListSerialization dataWithPropertyList:metadataDictionary format:NSPropertyListBinaryFormat_v1_0 options:0 error:NULL];
+ BOOL fileWriteResult = [data writeToFile:[self metadataFilePath] atomically:NO];
+ if (fileWriteResult == NO) {
+ NSString *message = [NSString stringWithFormat:@"*** FIC Error: %s couldn't write metadata for format %@", __PRETTY_FUNCTION__, [_imageFormat name]];
+ [[FICImageCache sharedImageCache] _logMessage:message];
+ }
+ });
}
- (void)_loadMetadata {

4 comments on commit f711496

Contributor

donholly replied Feb 17, 2014

This seems like it should help quite a bit! I'll test this out later today. Thanks for taking a look 👍

Without this patch, I was getting an 8ms/frame pause (on an iPhone 4S) when doing the property list serialization (line 612 in the patched code). The only remaining source of main thread pauses that I'm seeing are from contention over the lock in the methods under "Storing, Retrieving, and Deleting Entries", particularly when there are multiple caches misses in a row.

Contributor

donholly replied Mar 6, 2014

Yeah, this patch worked wonders for me. Thanks again, @mallorypaine!

This pull request should also help a bit with the serialization: #45

Contributor

mallorypaine replied Mar 6, 2014

@erichocean -- what is the exact backtrace of the main thread pause you're still seeing?

Please sign in to comment.