假設我有一個NSDictionary的一個的NSArray和NSDictionary中的兩個子集:基礎目標-c:帶數組的字典;用字典詞典
NSMutableDictionary *mkDict(void){
NSMutableDictionary *dict=[NSMutableDictionary dictionary];
NSMutableDictionary *sub=[NSMutableDictionary dictionary];
NSMutableArray *array= [NSMutableArray array];
[dict setObject:array forKey:@"array_key"];
[dict setObject:sub forKey:@"dict_key"];
return dict;
}
有很多方法來訪問子集的單個元素衆多,而且我選擇的時間其中三個。
第一種方式是通過訪問父的鍵間接訪問子元素:
void KVC1(NSMutableDictionary *dict, int count){
for(int i=0; i<count; i++){
char buf1[40], buf2[sizeof buf1];
snprintf(buf1,sizeof(buf1),"element %i", i);
snprintf(buf2, sizeof buf2, "key %i", i);
[[dict objectForKey:@"array_key"]
addObject:
[NSString stringWithUTF8String:buf1]];
[[dict objectForKey:@"dict_key"]
setObject:[NSString stringWithUTF8String:buf1]
forKey:[NSString stringWithUTF8String:buf2]];
}
}
第二個是使用的keyPath訪問:
void KVC2(NSMutableDictionary *dict, int count){
for(int i=0; i<count; i++){
char buf1[40], buf2[sizeof buf1], buf3[sizeof buf1];
snprintf(buf1,sizeof(buf1),"element %i", i);
snprintf(buf2, sizeof buf2, "key %i", i);
snprintf(buf3, sizeof buf3, "dict_key.key %i",i);
[dict insertValue:
[NSString stringWithUTF8String:buf1]
atIndex:i inPropertyWithKey:@"array_key"];
[dict setValue:
[NSString stringWithUTF8String:buf1]
forKeyPath:
[NSString stringWithUTF8String:buf3]];
}
}
而第三,類似於首先是訪問指向子元素的指針,然後使用該指針:
void KVC3(NSMutableDictionary *dict, int count){
NSMutableArray *subArray = [dict objectForKey:@"array_key"];
NSMutableDictionary *subDict = [dict objectForKey:@"dict_key"];
for(int i=0; i<count; i++){
char buf1[40], buf2[sizeof buf1];
snprintf(buf1,sizeof(buf1),"element %i", i);
snprintf(buf2, sizeof buf2, "key %i", i);
[subArray addObject:[NSString stringWithUTF8String:buf1]];
[subDict
setObject:
[NSString stringWithUTF8String:buf1]
forKey:
[NSString stringWithUTF8String:buf2]];
}
}
這裏是時刻碼:
#import <Foundation/Foundation.h>
#import <mach/mach_time.h>
// KVC1, KVC2 and KVC3 from above...
#define TIME_THIS(func,times) \
({\
mach_timebase_info_data_t info; \
mach_timebase_info(&info); \
uint64_t start = mach_absolute_time(); \
for(int i=0; i<(int)times; i++) \
func ; \
uint64_t duration = mach_absolute_time() - start; \
duration *= info.numer; \
duration /= info.denom; \
duration /= 1000000; \
NSLog(@"%i executions of line %i took %lld milliseconds", times, __LINE__, duration); \
});
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableDictionary *dict=mkDict();
NSMutableDictionary *dict2=mkDict();
NSMutableDictionary *dict3=mkDict();
TIME_THIS(KVC1(dict,1000),10);
TIME_THIS(KVC2(dict2,1000),10);
TIME_THIS(KVC3(dict3,1000),10);
if([dict isEqualToDictionary:dict2])
NSLog(@"And they are the same...");
[pool drain];
return 0;
}
下面是結果:
10 executions of line 256 took 57 milliseconds
10 executions of line 257 took 7930 milliseconds
10 executions of line 258 took 46 milliseconds
And they are the same...
問:爲什麼OS X雪豹/獅子建議使用KeyPaths所以臭慢的方法是什麼?如果將count
的大小增加到10,000或更多,則KVC2在其他兩種方法線性增加的情況下變得無限緩慢。
我做錯了什麼?訪問字典中的子集合的單個元素是否有更好的習慣用法?
+1'它的名字應該是它表演的線索。「好笑! :-) – 2011-04-29 19:42:35