2012-04-07 24 views
7

Tôi đang tìm cách ghi nhớ kết quả của hàm OCaml f có hai tham số (hoặc nhiều hơn, nói chung). Ngoài ra (và đây là phần khó), tôi muốn bản đồ nằm dưới quá trình này để quên một kết quả hoàn toàn nếu một trong hai giá trị của hai tham số là rác được thu thập.Kết quả ghi nhớ yếu của hàm đa tham số trong OCaml

Đối với hàm có chính xác một đối số, điều này có thể được thực hiện với mô-đun Weak và hàm f2tor Make một cách đơn giản. Để khái quát hóa điều này thành một cái gì đó có thể ghi nhớ các hàm có tính chất cao hơn, một giải pháp ngây thơ là tạo ra một bản đồ yếu từ các giá trị tuples đến các giá trị kết quả. Nhưng điều này sẽ không hoạt động chính xác đối với việc thu gom rác, vì bộ giá trị chỉ tồn tại trong phạm vi chức năng ghi nhớ, không phải mã khách hàng gọi f. Trong thực tế, các tài liệu tham khảo yếu sẽ được để các tuple, đó sẽ là rác thu thập ngay sau khi ghi nhớ (trong trường hợp xấu nhất).

Có cách nào để thực hiện việc này mà không cần triển khai lại Weak.Make không?

Tính năng băm nhỏ là trực giao với các yêu cầu của tôi và trên thực tế, không thực sự mong muốn đối với các giá trị của tôi.

Cảm ơn!

Trả lời

3

Thay vì lập chỉ mục bởi các tuple bạn có thể có một cấu trúc cây. Bạn sẽ có một bảng yếu được lập chỉ mục bởi tham số hàm đầu tiên có các mục là các bảng yếu thứ cấp. Các bảng phụ sẽ được lập chỉ mục theo tham số hàm thứ hai và chứa các kết quả ghi nhớ. Cấu trúc này sẽ quên kết quả chức năng ghi nhớ ngay sau khi tham số chức năng là GCed. Tuy nhiên, các bảng phụ sẽ được giữ lại miễn là tham số hàm đầu tiên là trực tiếp. Tùy thuộc vào kích thước của kết quả chức năng của bạn và sự phân bố của các thông số đầu tiên khác nhau, điều này có thể là một sự cân bằng hợp lý.

Tôi chưa thử nghiệm điều này. Ngoài ra nó có vẻ hợp lý rõ ràng.

+0

Tôi có thể xem cách thu thập rác của giá trị tham số đầu tiên sẽ dẫn đến giải phóng bảng tương ứng cho tham số thứ hai.Tuy nhiên, GCing một giá trị trong một bảng cho tham số thứ hai không có gì cho cha mẹ của nó (nếu mô-đun 'Yếu 'được sử dụng), ngay cả khi bản đồ kết quả trống. Tất nhiên điều này có thể được thực hiện bằng cách chủ động quét nội dung của bản đồ và xóa bất kỳ khóa thông số đầu tiên nào ánh xạ tới các bảng trống. – Nikos

+0

Phải, như tôi đã nói bảng phụ sẽ không được thu thập cho đến khi tham số đầu tiên được giải phóng. Nhưng giá trị trả lại được ghi nhớ sẽ được thu thập (có vẻ như với tôi). –

3

Một ý tưởng là thực hiện bộ sưu tập rác của riêng bạn.

Để đơn giản, hãy giả sử rằng tất cả đối số đều có cùng loại k.

Ngoài bảng yếu chính chứa các kết quả ghi nhớ được khóa bằng k * k, tạo bảng yếu thứ cấp chứa các đối số đơn loại k. Ý tưởng là để quét bảng chính một lần trong một thời gian và để loại bỏ các ràng buộc mà không còn muốn. Điều này được thực hiện bằng cách tìm kiếm các đối số trong bảng phụ; sau đó nếu bất kỳ trong số họ đã biến mất, bạn loại bỏ các ràng buộc từ bảng chính.

(Disclaimer: Tôi đã không kiểm tra này, nó có thể không hoạt động hoặc có thể có giải pháp tốt hơn)

+0

Điểm tốt. Có lẽ chỉ có một bảng là cần thiết, một bảng có các tham chiếu yếu như các khóa và đó là rác tùy chỉnh được thu thập lại một lần trong một thời gian bất cứ khi nào có bất kỳ tham chiếu yếu nào trong bộ đếm khóa biến mất. Điều này có thể được thực hiện thông qua finalizers? – Nikos

1

Tôi biết đây là một câu hỏi cũ, nhưng đồng nghiệp của tôi gần đây đã phát triển một thư viện tính toán gia tăng, được gọi là Adapton, có thể xử lý chức năng này. Bạn có thể tìm mã số here. Bạn có thể muốn sử dụng LazySABidi functor (những người khác là để chuẩn). Bạn có thể tìm trong thư mục Ứng dụng để biết các ví dụ về cách sử dụng thư viện. Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi nhiều hơn nữa.

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