Erlang的基准测试

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,哈哈都行呀。

相关推荐