Created
November 27, 2020 23:37
-
-
Save Catfish-Man/6942af953a9e48f80c2d6a6e6d86522f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import <time.h> | |
#define USE_CF_NONOBJC 1 | |
#if USE_CF_NONOBJC | |
extern CFTypeRef _CFNonObjCRetain(CFTypeRef cf); | |
extern void _CFNonObjCRelease(CFTypeRef cf); | |
#endif | |
extern id objc_retain(id obj); | |
extern void objc_release(id obj); | |
@interface RefCountOverrides : NSObject { | |
_Atomic(int64_t) refcount; | |
} | |
@end | |
@implementation RefCountOverrides | |
- (instancetype) init { | |
if ((self = [super init])) { | |
refcount = 1; | |
} | |
return self; | |
} | |
- (oneway void) release { | |
if (--refcount == 0) { | |
[self dealloc]; | |
} | |
} | |
- (id) retain { | |
++refcount; | |
return self; | |
} | |
@end | |
#define ITERS 20000000 | |
#define NSEC_PER_ITER(time) (((double)time * (double)NSEC_PER_SEC) / (double)ITERS) | |
#define TEST(body, name) do {\ | |
start = [NSDate date];\ | |
for (int i = 0; i < ITERS; i++) {\ | |
body\ | |
}\ | |
elapsed = -[start timeIntervalSinceNow];\ | |
if (baseline == 0) printf("Baseline of %f nanoseconds to -retain+-release an NSObject established\n", NSEC_PER_ITER(elapsed));\ | |
else printf("It was %.2fx as fast (%f nanoseconds) to use %s on %s \n", baseline / elapsed, NSEC_PER_ITER(elapsed), name, names[objIdx]);\ | |
} while (0) | |
int main() { | |
#define OBJECT_COUNT 8 | |
id objects[OBJECT_COUNT]; | |
objects[0] = [NSString stringWithUTF8String:"The quick brown fox jümps over the lazy dog!"]; | |
objects[1] = @"The quick brown fox jümps over the lazy dog!"; | |
objects[2] = (id)NSLocaleMeasurementSystem; | |
objects[3] = [NSString stringWithUTF8String:"The quick brown fox jumps over the lazy dog"]; | |
objects[4] = [[[NSObject alloc] init] autorelease]; | |
objects[5] = @5; | |
objects[6] = [[[RefCountOverrides alloc] init] autorelease]; | |
objects[7] = [NSURL fileURLWithPath:@"/System/Library/Frameworks/"]; | |
for (int objIdx = 0; objIdx < OBJECT_COUNT; objIdx++) { | |
id obj = objects[objIdx]; | |
objc_retain(obj); | |
objc_release(obj); | |
NSLog(@"%@", NSStringFromClass([obj class])); | |
} | |
const char *names[OBJECT_COUNT] = { "CFTypeRefs", "constant NSStrings", "constant NSStrings in the shared cache", "regular NSStrings", "NSObjects", "tagged NSObjects", "NSObjects with custom refcounting", "NSURLs" }; | |
NSDate *start = nil; | |
int objIdx = 0; | |
NSTimeInterval elapsed = 0; | |
NSTimeInterval baseline = 0; | |
TEST([objects[4] retain]; [objects[4] release];, "establish a baseline"); | |
baseline = elapsed; | |
for (int objIdx = 0; objIdx < OBJECT_COUNT; objIdx++) { | |
#if USE_CF_NONOBJC | |
if (objIdx == 0 || objIdx == 1 || objIdx == 2) { | |
TEST(_CFNonObjCRetain((CFTypeRef)objects[0]); _CFNonObjCRelease((CFTypeRef)objects[0]);, "_CFNonObjCRetain + _CFNonObjCRelease"); | |
} | |
#endif | |
TEST([objects[objIdx] retain]; [objects[objIdx] release];, "-retain + -release"); | |
TEST(objc_retain(objects[objIdx]); objc_release(objects[objIdx]);, "objc_retain + objc_release"); | |
TEST(CFRetain((CFTypeRef)objects[objIdx]); CFRelease((CFTypeRef)objects[objIdx]);, "CFRetain + CFRelease"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment