Memoization có một chức năng thuần túy (không chỉ là loại unit -> 'a
, nhưng bất kỳ khác quá) như một chìa khóa tra cứu là không thể bởi vì các hàm nói chung không có sự so sánh bình đẳng cho reason.
Dường như đối với loại chức năng cụ thể này unit -> 'a
, có thể sẽ có một bộ so sánh bình đẳng tùy chỉnh. Nhưng cách tiếp cận duy nhất để thực hiện so sánh đó vượt quá thái cực (phản ánh, IL, v.v.) sẽ là gọi hàm tra cứu là f1 = f2 iff f1() = f2()
, điều này dường như vô hiệu hóa bất kỳ cải thiện hiệu suất nào được mong đợi từ việc ghi nhớ.
Vì vậy, có lẽ, như đã được lưu ý, trong trường hợp này, tối ưu hóa nên được xây dựng xung quanh mẫu lazy
, nhưng không phải là memoization
.
CẬP NHẬT: Thật vậy, sau khi nhìn vào câu hỏi, tất cả đều nói về các hàm thiếu so sánh bình đẳng là chính xác, nhưng không áp dụng được, vì memoization xảy ra trong từng trường hợp riêng lẻ của từng chức năng cache
. Ở phía bên kia, đối với loại hàm cụ thể này có chữ ký unit->'a
, tức là tại hầu hết giá trị của đối số, sử dụng Dictionary
với hầu hết một mục nhập là quá mức cần thiết. sau khi thực hiện tương tự như trạng thái, nhưng đơn giản chỉ với một giá trị memoized sẽ làm:
let memoize2 f =
let notFilled = ref true
let cache = ref Unchecked.defaultof<'a>
fun() ->
if !notFilled then
cache := f()
notFilled := false
!cache
sử dụng như let foo = memoize2(fun() -> ...heavy on time and/or space calculation...)
với việc sử dụng đầu tiên foo()
thực hiện và lưu trữ các kết quả tính toán và tất cả liên tiếp foo()
chỉ tái sử dụng các giá trị được lưu trữ.
Nguồn
2013-12-12 18:21:52
Memoize thường được sử dụng để cache một số tính toán trên một đối số trong đó đối số được sử dụng làm khóa tra cứu. 'Lazy' là công cụ thích hợp trong trường hợp này. – Daniel
Bạn _could_ quấn 'lazy', một cái gì đó như thế này:' cho memoize f = let result = lazy (f()) trong fun() -> result.Value' – Daniel