2011-11-13 18 views
16
  1. Giả sử chúng ta có rất lớn NSDictionary, khi chúng ta muốn gọi phương thức objectForKey, nó sẽ làm cho rất nhiều hoạt động trong lõi để có được giá trị? Hoặc nó sẽ trỏ đến giá trị trong bộ nhớ trực tiếp?
  2. Làm thế nào nó hoạt động trong lõi?

Trả lời

27

Phần CFDictionary của Collections Programming Topics for Core Foundation (mà bạn nên xem xét nếu bạn muốn biết thêm) khẳng định:

Một từ điển-một đối tượng của CFDictionary kiểu là một băm dựa trên bộ sưu tập có phím để truy cập các giá trị của nó là tùy ý, các phần dữ liệu do chương trình xác định (hoặc con trỏ tới dữ liệu). Mặc dù khóa thường là một chuỗi (hoặc, trong Core Foundation, một đối tượng CFString), nó có thể là bất cứ thứ gì có thể vừa với kích thước của con trỏ — một số nguyên, một tham chiếu đối tượng Core Foundation, thậm chí một con trỏ vào một cấu trúc dữ liệu (có thể không như vậy).

Đây là những gì wikipedia đã nói về bảng băm:

Lý tưởng nhất, các hàm băm nên bản đồ mỗi phím có thể để một chỉ số khe cắm duy nhất, nhưng lý tưởng này là hiếm khi có thể đạt được trong thực tế (trừ trường hợp các khóa băm được cố định; tức là các mục mới không bao giờ được thêm vào bảng sau khi được tạo). Thay vào đó, hầu hết các thiết kế bảng băm cho rằng các va chạm băm — các khóa khác nhau ánh xạ tới cùng giá trị băm — sẽ xảy ra và phải được cung cấp theo một cách nào đó. Trong bảng băm có kích thước tốt, chi phí trung bình (số lượng hướng dẫn) cho mỗi lần tra cứu là độc lập với số lượng phần tử được lưu trữ trong bảng. Nhiều thiết kế bảng băm cũng cho phép chèn và xóa tùy ý các cặp khóa-giá trị , với giá trị trung bình hằng số (thực sự, khấu hao) cho mỗi hoạt động .

Hiệu suất do đó phụ thuộc vào chất lượng của hàm băm. Nếu nó là tốt thì các phần tử truy cập phải là một hoạt động O (1) (tức là không phụ thuộc vào số phần tử).

EDIT:

Trong thực tế sau khi đọc hơn nữa bộ sưu tập lập trình chủ đề cho Core Foundation, táo đưa ra một câu trả lời cho câu hỏi của bạn:

Thời gian truy cập cho một giá trị trong một đối tượng CFDictionary được đảm bảo ở mức thấp nhất O (log N) cho bất kỳ việc triển khai nào, nhưng thường là O (1) (thời gian cố định). Các hoạt động chèn hoặc xóa thường trong thời gian không đổi, nhưng là O (N * log N) trong trường hợp xấu nhất. Nó là nhanh hơn để truy cập các giá trị thông qua một khóa so với truy cập chúng trực tiếp. Từ điển có xu hướng sử dụng bộ nhớ nhiều hơn đáng kể so với một mảng có số lượng giá trị tương tự là .

+0

Xóa! Cảm ơn! ;) –

+0

Thực tế là nó cho thấy hoặc O (log N) hoặc O (1) làm cho tôi tự hỏi nếu họ có một màu đỏ thực hiện cây đen, hoặc nếu đăng nhập N tài khoản cho chuỗi trùng lặp. –

+1

@JustinMeiners Trường hợp xấu nhất là đối với các xung đột băm – JustSid

3

NSDictionary về cơ bản là cấu trúc Bảng băm, do đó Big-O để tra cứu là O (1). Tuy nhiên, để tránh phân bổ lại (và để đạt được độ phức tạp O (1)), bạn nên sử dụng dictionaryWithCapacity: để tạo một từ điển mới với kích thước phù hợp với kích thước của tập dữ liệu của bạn.

+6

Sử dụng từ điểnWithCông suất sẽ trong trường hợp bình thường cung cấp tối thiểu để không tăng hiệu suất. Trong thực tế, các tài liệu của Apple nói rằng nó chỉ là một gợi ý. Tôi có điểm chuẩn với kích thước NSArray từ 10 đến 10.000.000 và không tìm thấy lợi thế có ý nghĩa. Những bất lợi chính là thời gian và suy nghĩ chi tiêu vào tính toán đó là chi tiêu tốt hơn – zaph

+1

Bạn không thể đảm bảo sẽ không có va chạm trong bảng bất kể kích thước bảng. –

Các vấn đề liên quan