Shopify/identity_cache — pull request #133 by dylanahsmith (2014-03-06 23:34:06+00:00)
Title: Avoid extra deserialization for records from a cache miss.

@fbogsany for review

## Problem

On a cache miss in fetch_multi we serialize the record to save it in memcache. However, we also unnecessarily deserialize records that were just serialized.

## Solution

Use a hash to map keys to records loaded from the database, and use that over deserializing a coder.

## Benchmark

The FetchEmbed*Runner benchmarks are irrelevant, since they only use fetch, and not fetch_multi. The FetchNormalized*Runner benchmarks are more relevant, since fetch_multi is used to load the normalized associations, but the optimization will only help for misses.

Before

```
/Users/dylansmith/.rbenv/versions/2.1.0-github/bin/ruby ./performance/cpu.rb
Rehearsal: -------------------------------------------------------------
FindRunner: 1.120000 0.090000 1.210000 ( 7.113671)
FetchEmbedMissRunner: 1.730000 0.110000 1.840000 ( 8.168865)
FetchEmbedHitRunner: 0.180000 0.010000 0.190000 ( 0.224290)
FetchNormalizedMissRunner: 3.020000 0.240000 3.260000 ( 9.458525)
FetchNormalizedHitRunner: 0.240000 0.020000 0.260000 ( 0.320138)
------------------------------------------------------------------------
FindRunner: 1.150000 0.070000 1.220000 ( 7.249337)
FetchEmbedMissRunner: 1.750000 0.100000 1.850000 ( 8.204911)
FetchEmbedHitRunner: 0.160000 0.010000 0.170000 ( 0.194933)
FetchNormalizedMissRunner: 2.970000 0.240000 3.210000 ( 9.514133)
FetchNormalizedHitRunner: 0.240000 0.020000 0.260000 ( 0.320104)
```

after

```
Rehearsal: -------------------------------------------------------------
FindRunner: 1.190000 0.090000 1.280000 ( 7.189769)
FetchEmbedMissRunner: 1.730000 0.100000 1.830000 ( 8.027618)
FetchEmbedHitRunner: 0.180000 0.010000 0.190000 ( 0.221774)
FetchNormalizedMissRunner: 2.960000 0.230000 3.190000 ( 9.359317)
FetchNormalizedHitRunner: 0.250000 0.010000 0.260000 ( 0.326160)
------------------------------------------------------------------------
FindRunner: 1.110000 0.060000 1.170000 ( 7.364786)
FetchEmbedMissRunner: 1.760000 0.100000 1.860000 ( 8.352765)
FetchEmbedHitRunner: 0.180000 0.000000 0.180000 ( 0.216852)
FetchNormalizedMissRunner: 2.970000 0.240000 3.210000 ( 9.453474)
FetchNormalizedHitRunner: 0.250000 0.020000 0.270000 ( 0.319664)
```

It looks like there is an improvement in FetchNormalizedMissRunner, and any extra overhead for FetchNormalizedHitRunner is hard to notice among the noise in the results.