Performance Improvements

We recently found that this client's performance was insufficient for one of our use cases, and thus began the profiling. The punchline is that all the tests still pass and in a reader-oriented benchmark, performance improved 2.17x:

```
                                        Time    | Portion | Improvement
-----------------------------------------------------------------------
Baseline                                0.59349 | 1.00    | 1.00
Remove dense logger.debug call in read  0.54345 | 0.92    | 1.09
Tighter read lock acquisition           0.54529 | 0.92    | 1.09
More locals in read, fewer dots         0.53346 | 0.90    | 1.11
Branch reordering in Response.from_raw  0.53176 | 0.90    | 1.12
Import hot constants directly           0.52714 | 0.89    | 1.13
Import Response, Messages at top level  0.52645 | 0.89    | 1.13
Use a deque for pending messages        0.50857 | 0.86    | 1.17
Branch reordering in flush              0.50283 | 0.85    | 1.18
Avoid eager flush                       0.44162 | 0.74    | 1.34
Join pending messages together          0.27093 | 0.46    | 2.17
```

Methodology
==========
The benchmark is detailed in a shovel script (`shovel/profile.py`), and for each benchmark was run 125 times (in five groups of 25):

```bash
seq 25 | xargs -I^ shovel profile.basic --count=20000 2>/dev/null | grep Finished | cut -d' ' -f5 | sed 's#s##' | shovel profile.stats
```

The numbers above are the averages of the first five runs of each test. The targeted `nsqd` host was running locally and configured to be able to keep all benchmark messages in memory (in hopes of avoiding the performance characteristics of disk use).
Is there a useful upper bound on the batch sizes?