2014-09-28 60 views
1

我最近碰到一些代碼,看起來像下面傳來:如何將記錄存儲在erlang中,以及它們是如何變異的?

-record(my_rec, {f0, f1, f2...... f711}). 

update_field({f0, Val}, R) -> R#my_rec{f0 = Val}; 
update_field({f1, Val}, R) -> R#my_rec{f1 = Val}; 
update_field({f2, Val}, R) -> R#my_rec{f2 = Val}; 
.... 
update_field({f711, Val}, R) -> R#my_rec{f711 = Val}. 

generate_record_from_proplist(Props)-> 
    lists:foldl(fun update_field/2, #my_rec{}, Props). 

我的問題是關於什麼實際發生的記錄 - 可以說記錄了711場,我從proplist這樣產生了 - 因爲記錄是不可變的,所以至少在語義上,我們在foldr的每一步都會產生一個新的完整記錄 - 使得看起來像一個函數在參數長度上是線性的,然後變成實際上二次函數長度,因爲有更新對應於每個插入記錄的長度 - 我是否在這個假設中正確,或者編譯器是否足夠智能以保存我?

+1

[Erlang是否以任何聰明的方式實現記錄的拷貝和修改?](http://stackoverflow.com/questions/7207895/does-erlang-implement-record-copy-and-modify-in -any-clever-way) – tkowal 2014-09-28 07:21:52

回答

2

記錄是元組,其中第一個元素包含記錄的名稱,下一個記錄字段。

字段的名稱不存儲,它是編譯器,當然還有程序員的工具。我認爲它只是爲了避免寫入程序時字段順序錯誤,並且在釋放新版本時允許Tupple擴展而不重寫所有模式匹配。

您的代碼將生成712個元素元組的712個副本。

+0

我給了你pascal的要點 - 但我仍然想知道,erlang vm是否在一塊內存中存儲了一條記錄,或者是一個存儲在樹狀結構中的元組,使得更新更少然後痛苦地重建整個記錄從頭開始,如果它的第二個選項代碼虛擬機將能夠重用大量的引用。 – 2014-09-28 19:14:18

+0

你可以在這裏閱讀更多關於內部表示的內容:http://www.erlang-factory.com/upload/presentations/467/Halfword_EUC_2011.pdf它看起來像記錄是連續的記憶塊。 – tkowal 2014-09-28 21:27:20

+0

我正在尋找這個文件,但@tkowal比我快得多:o) – Pascal 2014-09-29 05:37:19

2

恐怕編譯器不夠聰明。 您可以在此SO answer閱讀更多。如果您有大量的字段,並且您想在O(1)時間內更新它,則應該使用ETS tables

相關問題