mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-01-12 09:33:41 +08:00
Rework RKManagedObjectMappingOperationDataSource to avoid performing mutable(Array|Set|OrderedSet)ValueForKeyPath: unless there are existing objects and the identificationAttributes are nil. refs #1232
This commit is contained in:
@@ -247,13 +247,15 @@ extern NSString * const RKObjectMappingNestingAttributeKeyName;
|
||||
NSManagedObject *managedObject = nil;
|
||||
|
||||
// If we are mapping within a relationship, try to find an existing object without identifying attributes
|
||||
// NOTE: We avoid doing the mutable(Array|Set|OrderedSet)ValueForKey if there are identification attributes for performance (see issue GH-1232)
|
||||
if (relationship) {
|
||||
id mutableArrayOrSetValueForExistingObjects = RKMutableCollectionValueWithObjectForKeyPath(mappingOperation.destinationObject, relationship.destinationKeyPath);
|
||||
NSArray *identificationAttributes = [entityMapping.identificationAttributes valueForKey:@"name"];
|
||||
for (NSManagedObject *existingObject in mutableArrayOrSetValueForExistingObjects) {
|
||||
id existingObjectsOfRelationship = identificationAttributes ? [mappingOperation.destinationObject valueForKeyPath:relationship.destinationKeyPath] : RKMutableCollectionValueWithObjectForKeyPath(mappingOperation.destinationObject, relationship.destinationKeyPath);
|
||||
if (existingObjectsOfRelationship && !RKObjectIsCollection(existingObjectsOfRelationship)) existingObjectsOfRelationship = @[ existingObjectsOfRelationship ];
|
||||
for (NSManagedObject *existingObject in existingObjectsOfRelationship) {
|
||||
if (! identificationAttributes) {
|
||||
managedObject = existingObject;
|
||||
[mutableArrayOrSetValueForExistingObjects removeObject:managedObject];
|
||||
[existingObjectsOfRelationship removeObject:managedObject];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
111
Code/Testing/RKBenchmark.h
Normal file
111
Code/Testing/RKBenchmark.h
Normal file
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// RKBenchmark.h
|
||||
// RestKit
|
||||
//
|
||||
// Derived from Benchmark class: https://gist.github.com/1479490
|
||||
// Created by Sijawusz Pur Rahnama on 03/02/09.
|
||||
// Copyleft 2009. Some rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
The `RKBenchmark` classes provide a simple, lightweight interface for quickly benchmarking the performance of units of code. Benchmark objects can be used procedurally, by manually starting & stopping the benchmark, or using a block interface to measure the execution time of the block.
|
||||
*/
|
||||
@interface RKBenchmark : NSObject
|
||||
|
||||
///---------------------------------
|
||||
/// @name Accessing Benchmark Values
|
||||
///---------------------------------
|
||||
|
||||
/**
|
||||
A name for the benchmark. Can be nil.
|
||||
*/
|
||||
@property (nonatomic, strong) NSString *name;
|
||||
|
||||
/**
|
||||
The start time of the benchmark as an absolute time value.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) CFAbsoluteTime startTime;
|
||||
|
||||
/**
|
||||
The end time of the benchmark as an absolute time value.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) CFAbsoluteTime endTime;
|
||||
|
||||
/**
|
||||
The elapsed time of the benchmark as determined by subtracting the end time from the start time. Returns zero until the benchmark has been stopped.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) CFTimeInterval elapsedTime;
|
||||
|
||||
///------------------------------------
|
||||
/// @name Quickly Performing Benchmarks
|
||||
///------------------------------------
|
||||
|
||||
/**
|
||||
*/
|
||||
+ (id)report:(NSString *)info executionBlock:(void (^)(void))block;
|
||||
|
||||
/**
|
||||
Performs a benchmark and returns a time interval measurement of the total time elapsed during the execution of the blocl.
|
||||
|
||||
@param block A block to execute and measure the elapsed time during execution.
|
||||
@return A time interval equal to the total time elapsed during execution.
|
||||
*/
|
||||
+ (CFTimeInterval)measureWithExecutionBlock:(void (^)(void))block;
|
||||
|
||||
///---------------------------------
|
||||
/// @name Creating Benchmark Objects
|
||||
///---------------------------------
|
||||
|
||||
/**
|
||||
Retrieves or creates a benchmark object instance with a given name.
|
||||
|
||||
@param name A name for the benchmark.
|
||||
@return A new or existing benchmark object with the given name.
|
||||
*/
|
||||
+ (RKBenchmark *)instanceWithName:(NSString *)name;
|
||||
|
||||
/**
|
||||
Creates and returns a benchmark object with a name.
|
||||
|
||||
@param name A name for the benchmark.
|
||||
@return A new benchmark object with the given name.
|
||||
*/
|
||||
+ (id)benchmarkWithName:(NSString *)name;
|
||||
|
||||
/**
|
||||
Initializes a new benchmark object with a name.
|
||||
|
||||
@param name The name to initialize the receiver with.
|
||||
@return The receiver, initialized with the given name.
|
||||
*/
|
||||
- (id)initWithName:(NSString *)name;
|
||||
|
||||
///----------------------------
|
||||
/// @name Performing Benchmarks
|
||||
///----------------------------
|
||||
|
||||
/**
|
||||
Runs a benchmark by starting the receiver, executing the block, and then stopping the benchmark object.
|
||||
|
||||
@param executionBlock A block to execute as the body of the benchmark.
|
||||
*/
|
||||
- (void)run:(void (^)(void))executionBlock;
|
||||
|
||||
/**
|
||||
Starts the benchmark by recording the start time.
|
||||
*/
|
||||
- (void)start;
|
||||
|
||||
/**
|
||||
Stops the benchmark by recording the stop time.
|
||||
*/
|
||||
- (void)stop;
|
||||
|
||||
/**
|
||||
Logs the current benchmark status. If the receiver has been stopped, the elapsed time of the benchmark is logged. If the benchmark is still running, the total time since the benchmark was started is logged.
|
||||
*/
|
||||
- (void)log;
|
||||
|
||||
@end
|
||||
129
Code/Testing/RKBenchmark.m
Normal file
129
Code/Testing/RKBenchmark.m
Normal file
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// RKBenchmark.h
|
||||
// RestKit
|
||||
//
|
||||
// Derived from Benchmark class: https://gist.github.com/1479490
|
||||
// Created by Sijawusz Pur Rahnama on 03/02/09.
|
||||
// Copyleft 2009. Some rights reserved.
|
||||
//
|
||||
|
||||
#import "RKBenchmark.h"
|
||||
|
||||
@interface RKBenchmark ()
|
||||
@property (nonatomic, assign, readwrite) CFAbsoluteTime startTime;
|
||||
@property (nonatomic, assign, readwrite) CFAbsoluteTime endTime;
|
||||
@property (nonatomic, assign, readwrite) CFTimeInterval elapsedTime;
|
||||
@property (nonatomic, assign, getter = isStopped) BOOL stopped;
|
||||
@end
|
||||
|
||||
@implementation RKBenchmark
|
||||
|
||||
static NSMutableDictionary *__sharedBenchmarks = nil;
|
||||
|
||||
+ (NSMutableDictionary *)sharedBenchmarks
|
||||
{
|
||||
if (!__sharedBenchmarks) {
|
||||
__sharedBenchmarks = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
return __sharedBenchmarks;
|
||||
}
|
||||
|
||||
+ (id)instanceWithName:(NSString *)name
|
||||
{
|
||||
@synchronized (self) {
|
||||
// get the benchmark or create it on-the-fly
|
||||
id benchmark = [[self sharedBenchmarks] objectForKey:name];
|
||||
if (!benchmark) {
|
||||
benchmark = [self benchmarkWithName:name];
|
||||
[[self sharedBenchmarks] setObject:benchmark forKey:name];
|
||||
}
|
||||
return benchmark;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@synthesize name = _name;
|
||||
@synthesize startTime = _startTime;
|
||||
@synthesize endTime = _endTime;
|
||||
@synthesize elapsedTime = _elapsedTime;
|
||||
@synthesize stopped = _stopped;
|
||||
|
||||
# pragma mark -
|
||||
# pragma mark Quick access class methods
|
||||
|
||||
+ (id)report:(NSString *)info executionBlock:(void (^)(void))block
|
||||
{
|
||||
RKBenchmark *benchmark = [self instanceWithName:info];
|
||||
[benchmark run:block];
|
||||
[benchmark log];
|
||||
return benchmark;
|
||||
}
|
||||
|
||||
+ (CFTimeInterval)measureWithExecutionBlock:(void (^)(void))block
|
||||
{
|
||||
RKBenchmark *benchmark = [self new];
|
||||
[benchmark run:block];
|
||||
return benchmark.elapsedTime;
|
||||
}
|
||||
|
||||
# pragma mark -
|
||||
# pragma mark Initializers
|
||||
|
||||
+ (id)benchmarkWithName:(NSString *)name
|
||||
{
|
||||
return [[self alloc] initWithName:name];
|
||||
}
|
||||
|
||||
- (id)initWithName:(NSString *)name
|
||||
{
|
||||
if (self = [self init]) {
|
||||
self.name = name;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
# pragma mark -
|
||||
# pragma mark Benchmark methods
|
||||
|
||||
- (void)run:(void (^)(void))executionBlock
|
||||
{
|
||||
[self start];
|
||||
executionBlock();
|
||||
[self stop];
|
||||
}
|
||||
|
||||
- (void)start
|
||||
{
|
||||
self.startTime = CFAbsoluteTimeGetCurrent();
|
||||
}
|
||||
|
||||
- (void)stop
|
||||
{
|
||||
self.endTime = CFAbsoluteTimeGetCurrent();
|
||||
self.stopped = YES;
|
||||
|
||||
// Calculate elapsed time
|
||||
CFDateRef startDate = CFDateCreate(NULL, self.startTime);
|
||||
CFDateRef endDate = CFDateCreate(NULL, self.endTime);
|
||||
self.elapsedTime = CFDateGetTimeIntervalSinceDate(endDate, startDate);
|
||||
CFRelease(startDate);
|
||||
CFRelease(endDate);
|
||||
}
|
||||
|
||||
- (void)log
|
||||
{
|
||||
CFTimeInterval timeElapsed;
|
||||
if (self.isStopped) {
|
||||
timeElapsed = self.elapsedTime;
|
||||
} else {
|
||||
CFDateRef startDate = CFDateCreate(NULL, self.startTime);
|
||||
timeElapsed = CFDateGetTimeIntervalSinceDate(startDate, (CFDateRef)[NSDate date]);
|
||||
CFRelease(startDate);
|
||||
}
|
||||
|
||||
// log elapsed time
|
||||
if (_name) NSLog(@"Benchmark '%@' took %f seconds.", _name, timeElapsed);
|
||||
else NSLog(@"Benchmark took %f seconds.", timeElapsed);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -469,6 +469,10 @@
|
||||
259D9861155218E5008C90F5 /* RKEntityCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D985D155218E4008C90F5 /* RKEntityCache.m */; };
|
||||
259D986415521B20008C90F5 /* RKEntityCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D986315521B1F008C90F5 /* RKEntityCacheTest.m */; };
|
||||
259D986515521B20008C90F5 /* RKEntityCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D986315521B1F008C90F5 /* RKEntityCacheTest.m */; };
|
||||
25A199D416ED035A00792629 /* RKBenchmark.h in Headers */ = {isa = PBXBuildFile; fileRef = 25A199D216ED035A00792629 /* RKBenchmark.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
25A199D516ED035A00792629 /* RKBenchmark.h in Headers */ = {isa = PBXBuildFile; fileRef = 25A199D216ED035A00792629 /* RKBenchmark.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
25A199D616ED035A00792629 /* RKBenchmark.m in Sources */ = {isa = PBXBuildFile; fileRef = 25A199D316ED035A00792629 /* RKBenchmark.m */; };
|
||||
25A199D716ED035A00792629 /* RKBenchmark.m in Sources */ = {isa = PBXBuildFile; fileRef = 25A199D316ED035A00792629 /* RKBenchmark.m */; };
|
||||
25A226D61618A57500952D72 /* RKObjectUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 25A226D41618A57500952D72 /* RKObjectUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
25A226D71618A57500952D72 /* RKObjectUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 25A226D41618A57500952D72 /* RKObjectUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
25A226D81618A57500952D72 /* RKObjectUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 25A226D51618A57500952D72 /* RKObjectUtilities.m */; };
|
||||
@@ -882,6 +886,8 @@
|
||||
259D985C155218E4008C90F5 /* RKEntityCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKEntityCache.h; sourceTree = "<group>"; };
|
||||
259D985D155218E4008C90F5 /* RKEntityCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKEntityCache.m; sourceTree = "<group>"; };
|
||||
259D986315521B1F008C90F5 /* RKEntityCacheTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKEntityCacheTest.m; sourceTree = "<group>"; };
|
||||
25A199D216ED035A00792629 /* RKBenchmark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKBenchmark.h; path = Testing/RKBenchmark.h; sourceTree = "<group>"; };
|
||||
25A199D316ED035A00792629 /* RKBenchmark.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKBenchmark.m; path = Testing/RKBenchmark.m; sourceTree = "<group>"; };
|
||||
25A226D41618A57500952D72 /* RKObjectUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectUtilities.h; sourceTree = "<group>"; };
|
||||
25A226D51618A57500952D72 /* RKObjectUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectUtilities.m; sourceTree = "<group>"; };
|
||||
25A34244147D8AAA0009758D /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; };
|
||||
@@ -1550,6 +1556,8 @@
|
||||
252EFB1F14D9A8D4004863C8 /* Testing */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
25A199D216ED035A00792629 /* RKBenchmark.h */,
|
||||
25A199D316ED035A00792629 /* RKBenchmark.m */,
|
||||
253477F615FFBD2E002C0E4E /* NSBundle+RKAdditions.h */,
|
||||
253477F515FFBD2E002C0E4E /* NSBundle+RKAdditions.m */,
|
||||
25055B8214EEF32A00B9C4DD /* RKTestFactory.h */,
|
||||
@@ -1809,6 +1817,7 @@
|
||||
25E88C88165C5CC30042ABD0 /* RKConnectionDescription.h in Headers */,
|
||||
25019495166406E30081D68A /* RKValueTransformers.h in Headers */,
|
||||
25A8C2341673BD480014D9A6 /* RKConnectionTestExpectation.h in Headers */,
|
||||
25A199D416ED035A00792629 /* RKBenchmark.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -1913,6 +1922,7 @@
|
||||
255893E4166BA7400010C70B /* RestKit-Prefix.pch in Headers */,
|
||||
255893E5166BA7700010C70B /* RKTestFixture.h in Headers */,
|
||||
25A8C2351673BD480014D9A6 /* RKConnectionTestExpectation.h in Headers */,
|
||||
25A199D516ED035A00792629 /* RKBenchmark.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -2267,6 +2277,7 @@
|
||||
25019497166406E30081D68A /* RKValueTransformers.m in Sources */,
|
||||
25A8C2361673BD480014D9A6 /* RKConnectionTestExpectation.m in Sources */,
|
||||
258BEA02168D058300C74C8C /* RKObjectMappingMatcher.m in Sources */,
|
||||
25A199D616ED035A00792629 /* RKBenchmark.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -2420,6 +2431,7 @@
|
||||
25019498166406E30081D68A /* RKValueTransformers.m in Sources */,
|
||||
25A8C2371673BD480014D9A6 /* RKConnectionTestExpectation.m in Sources */,
|
||||
258BEA03168D058300C74C8C /* RKObjectMappingMatcher.m in Sources */,
|
||||
25A199D716ED035A00792629 /* RKBenchmark.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#import "RKHuman.h"
|
||||
#import "RKChild.h"
|
||||
#import "RKParent.h"
|
||||
//#import "RKBenchmark.h"
|
||||
#import "RKBenchmark.h"
|
||||
|
||||
@interface RKManagedObjectMappingOperationDataSourceTest : RKTestCase
|
||||
|
||||
@@ -1143,78 +1143,77 @@
|
||||
expect([human isDeleted]).to.equal(YES);
|
||||
}
|
||||
|
||||
// TODO: Import bencharmk utility somehow...
|
||||
//- (void)testMappingAPayloadContainingRepeatedObjectsPerformsAcceptablyWithFetchRequestMappingCache
|
||||
//{
|
||||
// RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
|
||||
// RKFetchRequestManagedObjectCache *managedObjectCache = [RKFetchRequestManagedObjectCache new];
|
||||
// RKManagedObjectMappingOperationDataSource *mappingOperationDataSource = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext
|
||||
// cache:managedObjectCache];
|
||||
// managedObjectStore.managedObjectCache = managedObjectCache;
|
||||
//
|
||||
// RKEntityMapping *childMapping = [RKEntityMapping mappingForEntityForName:@"Child" inManagedObjectStore:managedObjectStore];
|
||||
// childMapping.identificationAttributes = @[ @"childID" ];
|
||||
// [childMapping addAttributeMappingsFromArray:@[@"name", @"childID"]];
|
||||
//
|
||||
// RKEntityMapping *parentMapping = [RKEntityMapping mappingForEntityForName:@"Parent" inManagedObjectStore:managedObjectStore];
|
||||
// [parentMapping addAttributeMappingsFromArray:@[@"parentID", @"name"]];
|
||||
// parentMapping.identificationAttributes = @[ @"parentID" ];
|
||||
// [parentMapping addRelationshipMappingWithSourceKeyPath:@"children" mapping:childMapping];
|
||||
//
|
||||
//
|
||||
// NSDictionary *mappingsDictionary = @{ @"parents": parentMapping };
|
||||
// NSDictionary *JSON = [RKTestFixture parsedObjectWithContentsOfFixture:@"benchmark_parents_and_children.json"];
|
||||
// RKMapperOperation *mapper = [[RKMapperOperation alloc] initWithObject:JSON mappingsDictionary:mappingsDictionary];
|
||||
// mapper.mappingOperationDataSource = mappingOperationDataSource;
|
||||
//
|
||||
// RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelOff);
|
||||
// RKLogConfigureByName("RestKit/CoreData", RKLogLevelOff);
|
||||
//
|
||||
// [RKBenchmark report:@"Mapping with Fetch Request Cache" executionBlock:^{
|
||||
// for (NSUInteger i = 0; i < 50; i++) {
|
||||
// [mapper performMapping];
|
||||
// }
|
||||
// }];
|
||||
// NSUInteger parentCount = [managedObjectStore.persistentStoreManagedObjectContext countForEntityForName:@"Parent" predicate:nil error:nil];
|
||||
// NSUInteger childrenCount = [managedObjectStore.persistentStoreManagedObjectContext countForEntityForName:@"Child" predicate:nil error:nil];
|
||||
// assertThatInteger(parentCount, is(equalToInteger(25)));
|
||||
// assertThatInteger(childrenCount, is(equalToInteger(51)));
|
||||
//}
|
||||
//
|
||||
//- (void)testMappingAPayloadContainingRepeatedObjectsPerformsAcceptablyWithInMemoryMappingCache
|
||||
//{
|
||||
// RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
|
||||
// RKInMemoryManagedObjectCache *managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
|
||||
// RKManagedObjectMappingOperationDataSource *mappingOperationDataSource = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext
|
||||
// cache:managedObjectCache];
|
||||
// managedObjectStore.managedObjectCache = managedObjectCache;
|
||||
//
|
||||
// RKEntityMapping *childMapping = [RKEntityMapping mappingForEntityForName:@"Child" inManagedObjectStore:managedObjectStore];
|
||||
// childMapping.identificationAttributes = @[ @"childID" ];
|
||||
// [childMapping addAttributeMappingsFromArray:@[@"name", @"childID"]];
|
||||
//
|
||||
// RKEntityMapping *parentMapping = [RKEntityMapping mappingForEntityForName:@"Parent" inManagedObjectStore:managedObjectStore];
|
||||
// [parentMapping addAttributeMappingsFromArray:@[@"parentID", @"name"]];
|
||||
// parentMapping.identificationAttributes = @[ @"parentID" ];
|
||||
// [parentMapping addRelationshipMappingWithSourceKeyPath:@"children" mapping:childMapping];
|
||||
//
|
||||
// NSDictionary *mappingsDictionary = @{ @"parents": parentMapping };
|
||||
// NSDictionary *JSON = [RKTestFixture parsedObjectWithContentsOfFixture:@"benchmark_parents_and_children.json"];
|
||||
// RKMapperOperation *mapper = [[RKMapperOperation alloc] initWithObject:JSON mappingsDictionary:mappingsDictionary];
|
||||
// mapper.mappingOperationDataSource = mappingOperationDataSource;
|
||||
// RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelOff);
|
||||
// RKLogConfigureByName("RestKit/CoreData", RKLogLevelOff);
|
||||
//
|
||||
// [RKBenchmark report:@"Mapping with In Memory Cache" executionBlock:^{
|
||||
// for (NSUInteger i = 0; i < 50; i++) {
|
||||
// [mapper performMapping];
|
||||
// }
|
||||
// }];
|
||||
// NSUInteger parentCount = [managedObjectStore.persistentStoreManagedObjectContext countForEntityForName:@"Parent" predicate:nil error:nil];
|
||||
// NSUInteger childrenCount = [managedObjectStore.persistentStoreManagedObjectContext countForEntityForName:@"Child" predicate:nil error:nil];
|
||||
// assertThatInteger(parentCount, is(equalToInteger(25)));
|
||||
// assertThatInteger(childrenCount, is(equalToInteger(51)));
|
||||
//}
|
||||
- (void)testMappingAPayloadContainingRepeatedObjectsPerformsAcceptablyWithFetchRequestMappingCache
|
||||
{
|
||||
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
|
||||
RKFetchRequestManagedObjectCache *managedObjectCache = [RKFetchRequestManagedObjectCache new];
|
||||
RKManagedObjectMappingOperationDataSource *mappingOperationDataSource = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext
|
||||
cache:managedObjectCache];
|
||||
managedObjectStore.managedObjectCache = managedObjectCache;
|
||||
|
||||
RKEntityMapping *childMapping = [RKEntityMapping mappingForEntityForName:@"Child" inManagedObjectStore:managedObjectStore];
|
||||
childMapping.identificationAttributes = @[ @"childID" ];
|
||||
[childMapping addAttributeMappingsFromArray:@[@"name", @"childID"]];
|
||||
|
||||
RKEntityMapping *parentMapping = [RKEntityMapping mappingForEntityForName:@"Parent" inManagedObjectStore:managedObjectStore];
|
||||
[parentMapping addAttributeMappingsFromArray:@[@"parentID", @"name"]];
|
||||
parentMapping.identificationAttributes = @[ @"parentID" ];
|
||||
[parentMapping addRelationshipMappingWithSourceKeyPath:@"children" mapping:childMapping];
|
||||
|
||||
|
||||
NSDictionary *mappingsDictionary = @{ @"parents": parentMapping };
|
||||
NSDictionary *JSON = [RKTestFixture parsedObjectWithContentsOfFixture:@"benchmark_parents_and_children.json"];
|
||||
RKMapperOperation *mapper = [[RKMapperOperation alloc] initWithRepresentation:JSON mappingsDictionary:mappingsDictionary];
|
||||
mapper.mappingOperationDataSource = mappingOperationDataSource;
|
||||
|
||||
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelOff);
|
||||
RKLogConfigureByName("RestKit/CoreData", RKLogLevelOff);
|
||||
|
||||
[RKBenchmark report:@"Mapping with Fetch Request Cache" executionBlock:^{
|
||||
for (NSUInteger i = 0; i < 50; i++) {
|
||||
[mapper start];
|
||||
}
|
||||
}];
|
||||
NSUInteger parentCount = [managedObjectStore.persistentStoreManagedObjectContext countForEntityForName:@"Parent" predicate:nil error:nil];
|
||||
NSUInteger childrenCount = [managedObjectStore.persistentStoreManagedObjectContext countForEntityForName:@"Child" predicate:nil error:nil];
|
||||
assertThatInteger(parentCount, is(equalToInteger(25)));
|
||||
assertThatInteger(childrenCount, is(equalToInteger(51)));
|
||||
}
|
||||
|
||||
- (void)testMappingAPayloadContainingRepeatedObjectsPerformsAcceptablyWithInMemoryMappingCache
|
||||
{
|
||||
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
|
||||
RKInMemoryManagedObjectCache *managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
|
||||
RKManagedObjectMappingOperationDataSource *mappingOperationDataSource = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext
|
||||
cache:managedObjectCache];
|
||||
managedObjectStore.managedObjectCache = managedObjectCache;
|
||||
|
||||
RKEntityMapping *childMapping = [RKEntityMapping mappingForEntityForName:@"Child" inManagedObjectStore:managedObjectStore];
|
||||
childMapping.identificationAttributes = @[ @"childID" ];
|
||||
[childMapping addAttributeMappingsFromArray:@[@"name", @"childID"]];
|
||||
|
||||
RKEntityMapping *parentMapping = [RKEntityMapping mappingForEntityForName:@"Parent" inManagedObjectStore:managedObjectStore];
|
||||
[parentMapping addAttributeMappingsFromArray:@[@"parentID", @"name"]];
|
||||
parentMapping.identificationAttributes = @[ @"parentID" ];
|
||||
[parentMapping addRelationshipMappingWithSourceKeyPath:@"children" mapping:childMapping];
|
||||
|
||||
NSDictionary *mappingsDictionary = @{ @"parents": parentMapping };
|
||||
NSDictionary *JSON = [RKTestFixture parsedObjectWithContentsOfFixture:@"benchmark_parents_and_children.json"];
|
||||
RKMapperOperation *mapper = [[RKMapperOperation alloc] initWithRepresentation:JSON mappingsDictionary:mappingsDictionary];
|
||||
mapper.mappingOperationDataSource = mappingOperationDataSource;
|
||||
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelOff);
|
||||
RKLogConfigureByName("RestKit/CoreData", RKLogLevelOff);
|
||||
|
||||
[RKBenchmark report:@"Mapping with In Memory Cache" executionBlock:^{
|
||||
for (NSUInteger i = 0; i < 50; i++) {
|
||||
[mapper start];
|
||||
}
|
||||
}];
|
||||
NSUInteger parentCount = [managedObjectStore.persistentStoreManagedObjectContext countForEntityForName:@"Parent" predicate:nil error:nil];
|
||||
NSUInteger childrenCount = [managedObjectStore.persistentStoreManagedObjectContext countForEntityForName:@"Child" predicate:nil error:nil];
|
||||
assertThatInteger(parentCount, is(equalToInteger(25)));
|
||||
assertThatInteger(childrenCount, is(equalToInteger(51)));
|
||||
}
|
||||
|
||||
- (void)testMappingIdentificationAttributesFromElementsOnAnArray
|
||||
{
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user