mohanzb 2010-02-08
需要测试Erlang系统各个方面的性能。
queue_test() -> Q = queue:new(), Q1 = queue:in(1), Q2 = queue:in(2), ok. -record(node_info, { var = 0, name, selected = 0, disks = [] }). disk_test() -> L = [ #node_info{name="node1", disks=[1,2,3,4]}, #node_info{name="node2", disks=[1,2]}, #node_info{name="node3", disks=[1,2]} ], disk_get(L, 0). move_head_to_tail([H|T]) -> T ++ [H]; move_head_to_tail([]) -> []. disk_total(L) -> lists:sum([length(D) || #node_info{disks=D} <- L]). disk_max([]) -> undifined; disk_max(L) -> [H|_] = lists:keysort(2, L), H. disk_get(L, Total) -> io:format("------------------------------------------~n"), receive after 1000 -> R = disk_get_n(L, Total, 2, []), io:format("Selected ~p~n", [element(1, R)]), disk_get(element(2, R), element(3, R)) end. disk_get_n(L, Total, 0, Acc) -> {Acc, L, Total}; disk_get_n(L, Total, N, Acc) -> Disks = disk_total(L), if Total =/= 0 -> L1 = [X#node_info{var=S/Total - length(D)/Disks} || #node_info{selected=S, disks=D} = X <- L]; true -> L1 = L end, #node_info{name=Name, selected=S, disks=D} = H = disk_max(L1), L2 = lists:keyreplace(Name, 3, L1, H#node_info{selected=S+1, disks=move_head_to_tail(D)}), disk_get_n(L2, Total+1, N-1, Acc ++ [H]).
问题:
因为变量的单次赋值原则,上述代码中不能对Q进行in-place修改。Q,Q1,Q2实现的效率如何?每次插入一元素,都要copy一份全新的数据结构出来吗?
所有的数据结构都面临这个问题。不过,ets可以通过idorname进行更新。
类似的还有函数参数的传值方式,对大的结构效率如何?
在ifclause中,L1=L为何必要?在分支的时候为了保证变量的安全性,在引入新的变量的时候,所有的分支都要正确的处理,在后面才能对新变量进行操作。关键是,L1=L的效率,是整个list的copy吗?还有,这种处理手法,毕竟有点别扭。
record的用法:用模式匹配提取字段比较好用。H#node_info.name这种用法别扭,代码过长。编译器知道H的实际类型,为何还要我们指明?换成H.name就方便的多了。或者H@name,哈哈都行呀。