Forgive me for the tangent: I tested the ARC and MRC (manual reference counting) version of this simple app that creates and drops a linked list a few times (keeping the list length within limits of the current ARC implementation). It did this in obj-c for simplicity (I suppose I'd get similar results for swift implementation that uses unowned references and some external table to keep strong references to the nodes).
ARC app
// ARC app
#import <Foundation/Foundation.h>
@interface Chained: NSObject {
@public Chained* next;
}
@end
@implementation Chained
@end
void test(void) {
NSLog(@"start");
double allocTime = 0;
double deallocTime = 0;
for (int i = 0; i < 10000; i++) {
double start = CFAbsoluteTimeGetCurrent();
Chained* first = nil;
for (int i = 1; i < 30000; i++) {
Chained* next = [Chained new];
next->next = first;
first = next;
}
allocTime += CFAbsoluteTimeGetCurrent() - start;
start = CFAbsoluteTimeGetCurrent();
first = nil;
deallocTime += CFAbsoluteTimeGetCurrent() - start;
}
NSLog(@"allocTime: %f, deallocTime: %f, totalTime: %f", allocTime, deallocTime, allocTime + deallocTime);
// allocTime: 21.279008, deallocTime: 32.589441, totalTime: 53.868450
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
test();
}
return 0;
}
MRC app
// MRC app
//specify -fno-objc-arc for this file in build phases
#import <Foundation/Foundation.h>
@interface Chained: NSObject {
@public Chained* next;
}
@end
@implementation Chained
@end
void test(void) {
NSLog(@"start");
double allocTime = 0;
double deallocTime = 0;
for (int i = 0; i < 10000; i++) {
double start = CFAbsoluteTimeGetCurrent();
Chained* first = nil;
for (int i = 1; i < 30000; i++) {
Chained* next = [Chained new];
next->next = first;
first = next;
}
allocTime += CFAbsoluteTimeGetCurrent() - start;
start = CFAbsoluteTimeGetCurrent();
while (first) {
Chained* cur = first;
first = cur->next;
[cur release];
}
deallocTime += CFAbsoluteTimeGetCurrent() - start;
}
NSLog(@"allocTime: %f, deallocTime: %f, totalTime: %f", allocTime, deallocTime, allocTime + deallocTime);
// allocTime: 15.840458, deallocTime: 18.275354, totalTime: 34.115811
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
test();
}
return 0;
}
Release mode, Intel mac:
ARC: allocTime: 21.27, deallocTime: 32.58, totalTime: 53.86
MRC: allocTime: 15.84, deallocTime: 18.27, totalTime: 34.11
oops. No free lunch with ARC.
PS. There are lies, damned lies, and benchmarks.