ReactiveCocoa/ReactiveCocoa — pull request #1313 by mattjgalloway (2014-05-08 20:13:08+00:00)
Title: Optimise RACObserve()

I did some performance benchmarking on pure RACObserve() behaviour, since I am using that a lot. I noticed that it was a *lot* slower than plain KVO. The test I did was as follows:

```
#define ITERATIONS 100000

@interface MyClass : NSObject
@property (nonatomic, strong) id value;
@end

@implementation MyClass @end

@interface Tester : NSObject @end

@implementation Tester

- (void)testRAC {
MyClass *obj = [MyClass new];
[RACObserve(obj, value) subscribeNext:^(id x){}];

NSDate *start = [NSDate date];
for (int i = 0; i < ITERATIONS; i++) { obj.value = @(i); }
NSDate *end = [NSDate date];
NSLog(@"%.5f", [end timeIntervalSinceDate:start]);
}

- (void)testKVO {
MyClass *obj = [MyClass new];
[obj addObserver:self forKeyPath:@"value" options:0 context:NULL];

NSDate *start = [NSDate date];
for (int i = 0; i < ITERATIONS; i++) { obj.value = @(i); }
NSDate *end = [NSDate date];
NSLog(@"%.5f", [end timeIntervalSinceDate:start]);

[obj removeObserver:self forKeyPath:@"value" context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {}

@end
```

This is the result before doing any optimisation:

```
RAC: 3.40782
KVO: 0.15069
```

And here is the result after the diffs in this PR:

```
RAC: 0.61605
KVO: 0.13659
```

And here is the RAC side of things with just each single diff applied:

```
Remove the extra RAC KVO keys: 2.64158
Remove the requirement for the reduceEach on rac_valuesForKeyPath: 1.23472
Optimise addDeallocObserverToPropertyValue: 3.21886
```

I think there's other things that could be done to improve the performance as well, but I wanted to get thoughts before trying anything else.