2012-04-03 24 views
18

Tôi muốn hiểu rõ hơn về thực tập của ví dụ: Data.Map. Khi tôi chèn một ràng buộc mới vào một Bản đồ, sau đó, vì tính bất biến của dữ liệu tôi lấy lại một cấu trúc dữ liệu mới giống hệt với cấu trúc dữ liệu cũ cộng với ràng buộc mới.Toàn bộ Bản đồ có được sao chép khi chèn một ràng buộc mới không?

Tôi muốn hiểu cách thực hiện điều này. Cuối cùng, trình biên dịch có triển khai thực hiện việc này hay không bằng cách sao chép toàn bộ cấu trúc dữ liệu với ví dụ: hàng triệu ràng buộc? Có thể nói chung rằng cấu trúc/mảng dữ liệu có thể thay đổi (ví dụ: Data.Judy) hoặc ngôn ngữ lập trình bắt buộc hoạt động tốt hơn trong các trường hợp như vậy? Dữ liệu bất biến có lợi thế gì khi nói đến từ điển/kho khóa-giá trị không?

Trả lời

31

Map được xây dựng trên cấu trúc dữ liệu cây. Về cơ bản, một giá trị Map mới được xây dựng, nhưng nó sẽ được điền gần như hoàn toàn bằng con trỏ tới cấu trúc cũ. Vì các giá trị không bao giờ thay đổi trong Haskell, đây là một tối ưu hóa an toàn và rất quan trọng, được gọi là chia sẻ.

Điều này có nghĩa là bạn có thể có nhiều phiên bản tương tự của cùng một cấu trúc dữ liệu treo xung quanh, nhưng chỉ các nhánh của cây khác biệt sẽ được lưu lại một lần nữa; phần còn lại sẽ chỉ đơn giản là con trỏ đến bản gốc của chi nhánh. Và, tất nhiên, nếu bạn vứt bỏ số Map cũ, các chi nhánh bạn đã thực hiện thay đổi sẽ được người thu gom rác thu hồi.

Chia sẻ là chìa khóa dẫn đến hiệu suất của cấu trúc dữ liệu không thay đổi. Bạn có thể tìm thấy this Wikipedia article hữu ích; nó có một số đồ thị khai sáng cho thấy dữ liệu sửa đổi được thể hiện bằng cách chia sẻ như thế nào.

+1

Câu trả lời không thể trả lời! –

+0

Nếu đây là tất cả các con trỏ mỗi khi chênh lệch tốc độ chèn vào [mảng Judy] (http://donsbot.wordpress.com/2009/09/26/very-fast-scalable-mutable-maps-and-hashes -for-haskell /) đến từ đâu? –

+3

@JFritsch: Vâng, nó vẫn phải xây dựng các phần đã sửa đổi của cây. Tuy nhiên, nếu bạn không cần bất kỳ ưu điểm bất biến có lợi thế nào (mô hình lập trình đơn giản hơn nhiều, bạn có thể giữ nhiều phiên bản được sửa đổi xung quanh mà không cần lưu trữ toàn bộ bản sao, vv), sau đó tất nhiên chỉ cần viết trực tiếp vào bộ nhớ sẽ nhanh hơn. Nhưng nó thường không phải là một sự khác biệt lớn như bạn nghĩ. – ehird

5

Data.Map không sao chép bản đồ cũ; nó (lazily) phân bổ các nút O (log N) mới, trỏ đến (và do đó chia sẻ) hầu hết các bản đồ cũ.

Vì "cập nhật" bản đồ không làm gián đoạn các phiên bản cũ, loại datastructure này cho phép bạn tự do hơn trong việc xây dựng các thuật toán đồng thời.

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