测试环境
Linux jason-lxw 3.2.0-39-generic #62-Ubuntu SMP Thu Feb 28 00:28:53 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
4G内存
Erlang R14B04 (erts-5.8.5) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.8.5 (abort with ^G)
1>
测试数据:
add()->
III="langxw",
MMM= 10,
OFFFFF = 100,
"display uuuuuuuuu, ffstate ," ++
" uuusername, uubio, "++
" uuavatar_url," ++
" uusex todo langgfriendship f , langgusers u where fffolllleriii=uuuuuuuuu " ++
" aaa | fffollllediii = '", III, "')" ++
" aaa Lype='1'" ++
" rrrr by ffctttte_datt ssss lllll " ++ integer_to_list(MMM) ++" FFeeee " ++ integer_to_list(OFFFFF) ++";".
concat()->
III="langxw",
MMM= 10,
OFFFFF = 100,
Sql = lists:concat(["display uuuuuuuuu, ffstate ,"
" uuusername, uubio, ",
" uuavatar_url,",
" uusex todo langgfriendship f , langgusers u where fffolllleriii=uuuuuuuuu ",
" aaa | fffollllediii = '", III, "')",
" aaa Type='1'",
" rrrr by ffctttte_datt ssss lllll ", MMM," FFeeee ", OFFFFF,";"
]).
lists:concat操作结果
49> test_lists_concat:start(1,10000). :参数:第一个参数是单进程,第二个参数是 add/concat执行次数
===============================================================
process #1 send 10000 request spent 62 ms
total spent=62 ms,avg spent=62 ms
=====================================================================
true
50> test_lists_concat:start(1,100000).
===============================================================
process #1 send 100000 request spent 554 ms
total spent=554 ms,avg spent=554 ms
=====================================================================
true
51> test_lists_concat:start(1,100 0000).
===============================================================
process #1 send 1000000 request spent 5699 ms
total spent=5699 ms,avg spent=5699 ms
=====================================================================
true
++操作结果
54> test_lists_concat:start(1,10000).
===============================================================
process #1 send 10000 request spent 2 ms
total spent=2 ms,avg spent=2 ms
=====================================================================
true
55> test_lists_concat:start(1,100000).
===============================================================
process #1 send 100000 request spent 27 ms
total spent=27 ms,avg spent=27 ms
=====================================================================
true
56> test_lists_concat:start(1,100 0000).
===============================================================
process #1 send 1000000 request spent 206 ms
total spent=206 ms,avg spent=206 ms
=====================================================================
true
57> test_lists_concat:start(1,10000000).
===============================================================
process #1 send 10000000 request spent 5257 ms
total spent=5257 ms,avg spent=5257 ms
=====================================================================
结论:(仅代表当前测试总结学习)乍看lists:concat源码,以为lists:concat执行效率会比++操作快,但实际测试结果,lists:concat远不如++操作。这可能因为lists:concat里面的递归(非尾递归)造成的。从上面测试数据可以看出lists:concat 比++操作要慢几十倍。
-module(test_lists_concat). -export([test/2]). -export([start/2,dotest/3]). start(Processes,Loops)-> ets:new(ib,[named_table,set]), [spawn(?MODULE,dotest,[self(),X,Loops])||X<-lists:seq(1,Processes)], recv(Processes,Loops), ets:delete(ib). recv(Processes,Loops)-> receive {fin,ProcessNum,Elapse}-> ets:insert(ib,{ProcessNum,Elapse}), case ets:info(ib,size) of Processes-> %%got all the resp print_result(Processes,Loops); _-> recv(Processes,Loops) end; Err-> io:format("recv unknowen msg~n"), recv(Processes,Loops) end. print_result(Processes,Loops)-> io:format("===============================================================~n"), TotalElapse= lists:foldr( fun({ProcessNum,Elapse},Acc)-> io:format("process #~p send ~p request spent ~p ms~n",[ProcessNum,Loops,Elapse]), Acc + Elapse end, 0, ets:tab2list(ib) ), AvgElapse=TotalElapse div Processes, io:format("total spent=~p ms,avg spent=~p ms~n",[TotalElapse,AvgElapse]), io:format("=====================================================================~n"). dotest(From,ProcessNum,Loops)-> Start=timestamp_in_millinsec(), [lists_concat()||X<-lists:seq(1,Loops)], Elapse=timestamp_in_millinsec()-Start, From!{fin,ProcessNum,Elapse}. timestamp_in_millinsec()-> {MegaSec,Sec,MicoSec}=erlang:now(), MegaSec * 1000000000+Sec*1000+MicoSec div 1000. lists_concat() -> %%lists:concat(["langxw", "langxw", "langxw"]), %%""++"langxw"++"langxw", %%concat(), add(), ok. add()-> III="langxw", MMM= 10, OFFFFF = 100, "display uuuuuuuuu, ffstate ," ++ " uuusername, uubio, "++ " uuavatar_url," ++ " uusex todo langgfriendship f , langgusers u where fffolllleriii=uuuuuuuuu " ++ " aaa | fffollllediii = '", III, "')" ++ " aaa Lype='1'" ++ " rrrr by ffctttte_datt ssss lllll " ++ integer_to_list(MMM) ++" FFeeee " ++ integer_to_list(OFFFFF) ++";". concat()-> III="langxw", MMM= 10, OFFFFF = 100, Sql = lists:concat(["display uuuuuuuuu, ffstate ," " uuusername, uubio, ", " uuavatar_url,", " uusex todo langgfriendship f , langgusers u where fffolllleriii=uuuuuuuuu ", " aaa | fffollllediii = '", III, "')", " aaa Type='1'", " rrrr by ffctttte_datt ssss lllll ", MMM," FFeeee ", OFFFFF,";" ]). test(Pro, Num)-> o.
补充:
51> test_lists_concat:start(1,100 0000).
===============================================================
process #1 send 1000000 request spent 5699 ms
total spent=5699 ms,avg spent=5699 ms
56> test_lists_concat:start(1,100 0000).
===============================================================
process #1 send 1000000 request spent 206 ms
@石头哥哥 这两次结果比较 ++ 比lists:concat快了大约27倍。
@erlang-菜鸟
个人理解(没测试)假设有两个list分别是A和B
1、如果A的长度远远大约B的长度时。A++B操作 会比 B++A慢
2、如果1成立,同样假设有A1,A2,A3,A4...An
如果A1长度>A2长短>A3长度>A4长度>...>An长度,
A1++A2++A3++A4++...++An 会比
{A4++..++An :记为R
A3++R :记为R
A2++R :记为R
A1++R
}慢。
基于这样的理解,简单的误认为lists:concat和++的快慢显示是错误的。还有就是lists:concat里面调用了非尾递归。感兴趣的同学继续测试一下。
找时间测试研究一下++操作顺序