Chinaunix首页 | 论坛 | 博客
  • 博客访问: 60479
  • 博文数量: 11
  • 博客积分: 102
  • 博客等级: 入伍新兵
  • 技术积分: 135
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-25 09:03
文章分类

全部博文(11)

文章存档

2018年(3)

2013年(5)

2011年(1)

2010年(2)

我的朋友

分类: Erlang

2018-01-03 17:39:02

对于lists:substract(-- 操作)的性能,官方文档中解释说与两列表的乘积成正比,如果列表太长,用ordsets:substract更合适,网上也有一些文章提到,比如

http://blog.csdn.net/mycwq/article/details/32160581

这篇文章提到


那么,问题就来了,列表多长算太长,什么时候lists:substract,什么时候用改进方案,还是lists:subtract就直接废掉了呢。

对于以上的疑问做了以下测试。测试代码如下,对不同的列表长度进行用两种方法进行了实测。Len为列表长度,N为每个长度取样本次数,N越大误差超小,最后的时间为N次样本的总和。

-module(test).

-compile(export_all).

 

lists_subtract(N, Len) ->

        List1 = List2 = lists:seq(1, Len),

        Fun = fun() -> List1 -- List2 end,

        run(N, Len, Fun).

 

lists_gb_set_subtract(N, Len) ->

        List1 = List2 = lists:seq(1, Len),

        Fun = fun() -> 

                        Set = gb_sets:from_list(List2),

                        [E || E <- List1, not gb_sets:is_element(E, Set)]

        end,

        run(N, Len, Fun).

 

run(N, Len, Fun) ->

        {T, _} = timer:tc(fun() -> loop(N, Fun) end),

        io:format("~w ~w~n",[Len,T]).

 

 

loop(N, Fun) when N > 0 ->

        Fun(),

        loop(N - 1, Fun);

loop(_, _) ->

        done.

 

 

测试分两阶段,

第一阶段,列表起始长度Len100,按步长为10递增至1000。结果显示,

1, 当Len < 550lists:subtract 优于gb_set,而且Len越小lists:subtract优势超明显。

2, 当550 < Len < 650,gb_set 反转优于lists:subtract ,但二者相关不大。

3, 当 650 < len < 900,lists:subtract 又反转优于 gb_set,二者伯仲之间。

当 900 < len < 1000, gb_set 重新优于 lists:subtract,并且优势有扩大的趋势。


第二阶段,列表起始长度Len100,按步长为100递增至5000。该阶段重点关注Len>1000的情况。结果显示,lists:subtract性能退化非常严重,gb_set的优势得以体现,以绝对优势取胜。



综上所述,开篇的疑问就都一一得出答案了。什么情况下使用使用哪一种方法,还是要看具体的需求:

1, 对于有大量的、频繁的小列表(建议长度一般在500以下 )操作,建议使用lists:subtract 更高效。

2, 对于有少量小列表操作,使用哪种都无所谓。

3, 对于长度在500900区间的列表,使用哪种都可以,性能在伯仲之间。

4, 对于列表长度在900以上的长列表,建议使用gb_set优化方案。


阅读(35047) | 评论(0) | 转发(0) |
0

上一篇:Linux中的list_entry和container_of

下一篇:没有了

给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册