RestKit/RestKit — pull request #2081 by carllindberg (2014-11-07 18:41:55+00:00)
Title: Add caching for different property mapping types

There are a few intertwined changes here, found during #2065 investigations.

First, in RKMappingOperation, the applyNestingToMappings: method used allKeys.lastObject and allValues.lastObject to get the nesting key and value. That implementation implies there can only ever be one key and value in the dictionary, and of course obtaining those values in that manner creates two additional NSArray instances. So, I changed to have separate nesting key and value properties, and to use them directly. The testing app does not use the nested mappings so there is no measurable improvement there, but there was one in my real application (even just using objectForKey: to obtain the value, avoiding the allValues, helped a little).

Second, obtaining the attribute versus relationship mappings calculated them on the fly during the mapping operation, whereas if we cache those in the RKObjectMapping, the work is done once and not for each mapped object which uses that mapping.

Third, the calculation of simple vs keyPath attribute mappings during the mapping operation was somewhat of a hotspot. They were only called once, but the same basic logic was used in both. However... if there is no nested substitution in effect, then we could also cache those at the RKObjectMapping level and use that NSArray instance directly without calculating anything. So, I added simple vs keyPath attribute storage in RKObjectMapping, and if there is no nested substitution at all, then we can simply use the RKObjectMapping values directly. If there is substitution, we apply it, then cache the results -- that still saves one trip through the array with rangeOfString: checks, but substitution should be relatively rare.

The result is a fairly significant speedup.

Timings before:
(Device) Mapping 5000 students with relationship mapping: 20.827214
(Simulator) Mapping 5000 students with relationship mapping: 2.909065

Timings after:
(Device) Mapping 5000 students with relationship mapping: 17.945234
(Simulator) Mapping 5000 students with relationship mapping: 2.567544