vui Benchmark :)
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{ @autoreleasepool {
NSMutableSet *masterSet = [NSMutableSet set];
for (NSInteger i = 0; i < 100000; i++) {
[masterSet addObject:[NSNumber numberWithInteger:i]];
}
clock_t start = clock();
for (NSInteger i = 0; i < 100; i++) {
@autoreleasepool {
[NSMutableSet setWithSet:masterSet];
}
}
NSLog(@"a: --- %lu", clock() - start);
sleep(1);
start = clock();
for (NSInteger i = 0; i < 100; i++) {
@autoreleasepool {
[[masterSet mutableCopy] autorelease];
}
}
NSLog(@"b: --- %lu", clock() - start);
return 0;
} }
Trên máy tính của tôi (10.7), setWithSet: là ~ 3x chậm hơn so với -mutableCopy (Có ai đó muốn thử trên iOS 5? :))
Bây giờ, câu hỏi đặt ra là: tại sao?
-mutableCopy đang dành phần lớn thời gian của mình trong CFBasicHashCreateCopy() (xem CFBasicHash.m). Điều này có vẻ như đang sao chép các nhóm băm trực tiếp, không có phục hồi.
Running Time Self Symbol Name
256.0ms 61.5% 0.0 -[NSObject mutableCopy]
256.0ms 61.5% 0.0 -[__NSCFSet mutableCopyWithZone:]
256.0ms 61.5% 0.0 CFSetCreateMutableCopy
255.0ms 61.2% 156.0 CFBasicHashCreateCopy
97.0ms 23.3% 44.0 __CFSetStandardRetainValue
-setWithSet liệt kê thông qua mỗi giá trị của tập hợp và sau đó thêm nó vào bộ mới. Từ việc thực hiện CFBasicHashAddValue (một lần nữa trong CFBasicHash.m), có vẻ như nó đang khôi phục từng giá trị trong tập hợp.
Running Time Self Symbol Name
1605.0ms 86.0% 0.0 +[NSSet setWithSet:]
1605.0ms 86.0% 2.0 -[NSSet initWithSet:copyItems:]
1232.0ms 66.0% 68.0 -[__NSPlaceholderSet initWithObjects:count:]
1080.0ms 57.8% 299.0 CFBasicHashAddValue
324.0ms 17.3% 28.0 -[NSSet getObjects:count:]
272.0ms 14.5% 75.0 __CFBasicHashFastEnumeration
Việc khôi phục này có ý nghĩa ở cấp CFSet. CFSets lấy CFSetHashCallBack trong tham số callBacks; do đó, hai CFSets của CFNumbers có thể có một quy trình băm khác nhau được chỉ định. NSSet của Foundation sử dụng CFSet dưới mui xe, và có hàm CFSetHashCallBack gọi -[NSObject hash]
. (Mặc dù tôi đoán rằng Apple có thể tối ưu hóa trường hợp này và tránh rehash khi hai bộ có cùng một hàm gọi lại băm).
Lưu ý rằng điểm chuẩn này chỉ dành cho NSSet (của NSNumbers), các lớp thu thập khác có thể có các đặc tính hiệu suất khác nhau.
Câu hỏi hay và tôi nghi ngờ có khả năng có nhiều tranh luận về vấn đề này. –
Nếu bạn muốn làm tất cả mọi người một ưu tiên, chuẩn nó và trả lời câu hỏi cho mình :) Tôi nghi ngờ không nên có nhiều sự khác biệt, mặc dù. – fzwo
@fzwo Tôi đoán tôi có thể làm điều đó .. Mặc dù đó là một phần câu hỏi triết lý lập trình :) – nielsbot