ReactiveCocoa/ReactiveCocoa — pull request #858 by jspahrsummers (2013-10-11 05:40:26+00:00)
Title: Split primitive signal behaviors into separate classes

This moves the implementations for each of `+error:`, `+empty`, `+return:`, and `+createSignal:` into their own classes, reducing memory usage and optimizing subscription for the former three cases (since the latter is, far and away, the most complex).

As a consequence of these changes, `RACSubject` now has its own subscription behavior as well, and no longer [keeps itself alive](https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/Documentation/MemoryManagement.md) for one run loop iteration while waiting for subscribers. Although this is technically a breaking change, that behavior was only ever intended to benefit `RACSignal`, so my jimmies remain unrustled.

### Stats

After making this change, it became much easier to see the breakdown of signal types. Using a completely unscientific run of GitHub for Mac for ~15 seconds, this is what I ended up with:

* `RACEmptySignal` — 2,633 overall allocations
* `RACDynamicSignal` — 21,926
* `RACErrorSignal` — 0 _(this was initially surprising to me, but makes sense when you consider the exception-like behavior of signal errors)_
* `RACReturnSignal` — 25,046
* `RACSubject` — 560

This is strong support for the refactoring I did, since **signals created with `+return:` and friends now occupy less memory than before**. It also backs up my decision to use `@synchronized` in place of a spin lock in `RACSubject` (because it's not as important).

Since you're dying to know, I also profiled CPU time before and after this change, following a similar usage pattern as above. **The speedup is seriously ridiculous.**

In the below screenshots, I've highlighted all RAC frames above 100ms. You can also check out the [raw traces](https://dl.dropboxusercontent.com/u/92083149/RACSignal-split-profiles.zip) if you're curious.

**Before:**
![before](https://f.cloud.github.com/assets/432536/1312436/97e576a4-3237-11e3-9f5f-70ad57d70125.png)

**After:**
![after](https://f.cloud.github.com/assets/432536/1312437/9c50a470-3237-11e3-9a95-a6b6271f131c.png)

:boom::camel: