Tôi có một từ điển có chứa từ điển thứ hai với 1000 mục nhập. Các mục nhập là tất cả NSStrings của loại khóa = key XXX
và giá trị = element XXX
trong đó XXX
là số từ 0 - số lượng phần tử - 1. (Vài ngày trước, tôi đã hỏi về từ điển Objective-C có chứa từ điển. Vui lòng refer to that question nếu bạn muốn mã tạo từ điển.)Mục tiêu-c: Vấn đề với các khối và NSEnumerationConcurrent
Tổng chiều dài của tất cả các chuỗi trong từ điển phụ là 28.670 ký tự. tức là:
strlen("key 0")+strlen("element 0")+
//and so on up through
strlen("key 999")+strlen("element 999") == 28670.
Hãy xem xét giá trị băm rất đơn giản này như một chỉ báo nếu phương pháp đã liệt kê mọi cặp khóa + giá trị một lần và chỉ một lần.
tôi có một chương trình con mà làm việc một cách hoàn hảo (sử dụng khối) để truy cập phím từ điển cá nhân và các giá trị:
NSUInteger KVC_access3(NSMutableDictionary *dict){
__block NSUInteger ll=0;
NSMutableDictionary *subDict=[dict objectForKey:@"dict_key"];
[subDict
enumerateKeysAndObjectsUsingBlock:
^(id key, id object, BOOL *stop) {
ll+=[object length];
ll+=[key length];
}];
return ll;
}
// will correctly return the expected length...
Nếu tôi thử các khối đồng thời cùng sử dụng (trên một máy tính đa xử lý), tôi nhận được một số gần nhưng không chính xác 28.670 mong đợi:
NSUInteger KVC_access4(NSMutableDictionary *dict){
__block NSUInteger ll=0;
NSMutableDictionary *subDict=[dict objectForKey:@"dict_key"];
[subDict
enumerateKeysAndObjectsWithOptions:
NSEnumerationConcurrent
usingBlock:
^(id key, id object, BOOL *stop) {
ll+=[object length];
ll+=[key length];
}];
return ll;
}
// will return correct value sometimes; a shortfall value most of the time...
các tài liệu Apple cho NSEnumerationConcurrent
nhà nước:
"the code of the Block must be safe against concurrent invocation."
Tôi nghĩ rằng đó có thể là vấn đề, nhưng vấn đề với mã của tôi hoặc khối trong số KVC_access4
KHÔNG an toàn cho yêu cầu đồng thời là gì?
Sửa & Kết luận
Nhờ BJ Homer excellent solution, tôi đã NSEnumerationConcurrent làm việc. Tôi đã hẹn giờ cả hai phương pháp. Mã tôi có ở trên trong KVC_access3
nhanh hơn và dễ dàng hơn cho các từ điển vừa và nhỏ. Nó nhanh hơn rất nhiều trên nhiều từ điển. Tuy nhiên, nếu bạn có từ điển lớn mongo (hàng triệu hoặc hàng chục triệu cặp khóa/giá trị) thì mã này:
[subDict
enumerateKeysAndObjectsWithOptions:
NSEnumerationConcurrent
usingBlock:
^(id key, id object, BOOL *stop) {
NSUInteger workingLength = [object length];
workingLength += [key length];
OSAtomicAdd64Barrier(workingLength, &ll);
}];
là nhanh hơn đến 4x. Điểm chéo cho kích thước là khoảng 1 từ điển của 100.000 yếu tố thử nghiệm của tôi. Nhiều từ điển hơn và điểm giao nhau cao hơn có lẽ là do thời gian thiết lập.