我最近遇到了一些类似于以下内容的代码:
-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个字段并且我从一个名单生成它 - 因为记录是不可变的,我们至少在语义上会产生一个新的记录折叠器中的每一步 - 使得看起来像是一个在参数长度上呈线性的函数,成为长度中实际上是二次的函数,因为每个插入的记录长度都有相应的更新 - Am我在这个假设中是正确的,或者编译器足够智能 救我?
答案 0 :(得分:2)
恐怕编译器不够聪明。 您可以在此SO answer中阅读更多内容。如果您有大量字段并且想要在O(1)时间内更新它,则应使用ETS tables。
答案 1 :(得分:2)
记录是元组,第一个元素包含记录的名称,下一个元素包含记录字段。
不存储字段的名称,它是编译器的工具,当然还有程序员。我认为它的引入只是为了避免在编写程序时出现字段顺序错误,并且在发布新版本时允许tupple扩展而不重写所有模式匹配。
您的代码将生成712个元组的712个副本。