為了注冊稍后呼叫的單元函式,我想出了這個使用(unit -> unit) ref將函式鏈接在一起的解決方案:
let callbacks = ref @@ fun () -> ()
let add_callback f =
let old_callbacks = !callbacks in
callbacks := (fun () -> f (); old_callbacks ())
(* ... call add_callback many times ... *)
(* eventually, run all the callbacks I stacked: *)
!callbacks ()
我想知道它與使用函式堆疊的其他解決方案相比如何(unit -> unit) list ref:
let callbacks = ref []
let add_callback f =
callbacks := f :: !callbacks
(* ... call add_callback many times ... *)
(* eventually, run all the callbacks I stacked: *)
List.iter (fun f -> f ()) !callbacks
它們在記憶體中的表示方式是否存在差異?
如果我要注冊大量函式,從記憶體和拆垛時間來看,哪種解決方案是最好的?對于這兩個標準,是否有更好的解決方案?
uj5u.com熱心網友回復:
在這兩種情況下,您都有一個函式串列。在第一種情況下,串列的節點是函式閉包。在第二種情況下,它們是缺點元素。我不知道 OCaml 中閉包表示的來龍去脈,但我猜想閉包比 cons 元素大(它需要 3 個記憶體插槽用于 header、car 和 cdr(使用舊學校術語))。
當需要呼叫時,兩種情況都會獲取指向下一個函式的指標并呼叫它。在第一種情況下,指標將從閉包的環境(變數系結)中獲取。在第二種情況下,它將從缺點中獲取。我懷疑環境的訪問效率與 cons 單元大致相同。即,代碼可以使用固定偏移量而不是符號查找。
這些只是猜測。對兩種不同的方法進行編碼并比較它們實際上會很有趣(也很有趣)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/391627.html
上一篇:基于文本的游戲。主功能
下一篇:忽略省略號函式中的引數缺失錯誤
