需要测试Erlang系统各个方面的性能。
[list]
[*] 进程创建和并发能力
[*] 大数据量的消息传输
[/list]
问题:
因为变量的单次赋值原则,上述代码中不能对Q进行in-place修改。Q,Q1,Q2实现的效率如何?每次插入一元素,都要copy一份全新的数据结构出来吗?
[b]
所有的数据结构都面临这个问题。不过,ets可以通过id or name进行更新。
[/b]
类似的还有函数参数的传值方式,对大的结构效率如何?
在if clause中,L1=L为何必要?在分支的时候为了保证变量的安全性,在引入新的变量的时候,所有的分支都要正确的处理,在后面才能对新变量进行操作。关键是,L1=L的效率,是整个list的copy吗?还有,这种处理手法,毕竟有点别扭。
record的用法:用模式匹配提取字段比较好用。H#node_info.name这种用法别扭,代码过长。编译器知道H的实际类型,为何还要我们指明?换成H.name就方便的多了。或者H@name,哈哈都行呀。 :wink:
[list]
[*] 进程创建和并发能力
[*] 大数据量的消息传输
[/list]
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一份全新的数据结构出来吗?
[b]
所有的数据结构都面临这个问题。不过,ets可以通过id or name进行更新。
[/b]
类似的还有函数参数的传值方式,对大的结构效率如何?
在if clause中,L1=L为何必要?在分支的时候为了保证变量的安全性,在引入新的变量的时候,所有的分支都要正确的处理,在后面才能对新变量进行操作。关键是,L1=L的效率,是整个list的copy吗?还有,这种处理手法,毕竟有点别扭。
record的用法:用模式匹配提取字段比较好用。H#node_info.name这种用法别扭,代码过长。编译器知道H的实际类型,为何还要我们指明?换成H.name就方便的多了。或者H@name,哈哈都行呀。 :wink: