erlang进程间发送消息的性能
来源:互联网 发布:台州淘宝美工 编辑:程序博客网 时间:2024/05/16 18:51
测试起因
erlang 语言是建议多建进程(erlang自己的进程,不是操作系统进程),利用消息来协同进程,实现高并发。
要实际在项目中使用,就必须知道erlang进程创建的速度,进程间消息通信的速度,消息通信对内存的影响。
根据这些性能数据,才好判断进程需要切分到什么样的粒度,才能预估一个系统架构的大致性能水平。
书上没说,所以自己动手测试下。
erlang进程创建的速度
erlang的进程,其实在内部实现中,仅是个数据结构,根据 erlang程序设计 书中的代码,测试了下,启动10000个进程,平均每个进程需要1us~3us之间,每个进程的内存开销约3K。 如果仅新增了一个数据结构,这个时间消耗大了点。
但不管启动多少个进程,从操作系统上看到的erl的线程数都是8个。
测试过程如下:
Eshell V5.9.2 (abort with ^G)
1> processor:max(10000). %表示创建1万个进程,不销毁
Max allowed processes: 32768
Process spawn time= 3.0 (4.1) usecond
24
2> processor:max(10000).
Max allowed processes: 32768
Process spawn time= 2.0 (4.0) usecond
24
3> processor:max(10000).
Max allowed processes: 32768
Process spawn time= 4.0 (4.1) usecond
24
4> processor:max(10000).
Max allowed processes: 32768
=ERROR REPORT==== 26-Sep-2012::11:10:06 ===
Too many processes
3次执行前后,内存增长分别为:
第一次:33.05078125 M
第二次:27.36328125 M
第三次:25.4453125 M
代码如下:
-module(processor).
-export([max/1]).
max(N) ->
Max = erlang:system_info(process_limit),
io:format("Max allowed processes: ~p~n", [Max]),
statistics(runtime),
statistics(wall_clock),
L = for(1, N, fun()-> spawn(fun()-> wait() end) end),
{_, Time1} = statistics(runtime),
{_, Time2} = statistics(wall_clock),
% lists:foreach(fun(Pid) -> Pid ! die end, L),
U1 = Time1 *1000 / N,
U2 = Time2 *1000 / N,
io:format("Process spawn time= ~p (~p) microsecond~n",
[U1, U2]),
1+5,
21+3.
wait() ->
receive
die ->
void
end.
for(N, N, F) ->
[F()];
for(I, N, F) ->
[F()|for(I+1, N, F)].
-export([max/1]).
max(N) ->
Max = erlang:system_info(process_limit),
io:format("Max allowed processes: ~p~n", [Max]),
statistics(runtime),
statistics(wall_clock),
L = for(1, N, fun()-> spawn(fun()-> wait() end) end),
{_, Time1} = statistics(runtime),
{_, Time2} = statistics(wall_clock),
% lists:foreach(fun(Pid) -> Pid ! die end, L),
U1 = Time1 *1000 / N,
U2 = Time2 *1000 / N,
io:format("Process spawn time= ~p (~p) microsecond~n",
[U1, U2]),
1+5,
21+3.
wait() ->
receive
die ->
void
end.
for(N, N, F) ->
[F()];
for(I, N, F) ->
[F()|for(I+1, N, F)].
erlang的消息
写了个测试程序,自己给自己发消息
%%% yqmsg.erl
-module(yqmsg).
-export([max/1,wait/0]).
max(N) ->
io:format("PID=~p,Max Message: ~p~n", [self(),N]),
statistics(runtime),
statistics(wall_clock),
L = for(1, N, fun()->self()!{testmsg,"1234567890abcdefghijklmnopqrstuvwxyz#$%^ABCDEFGHIJ"} end),
{_, Time1} = statistics(runtime),
{_, Time2} = statistics(wall_clock),
U1 = Time1 *1000/ N,
U2 = Time2 *1000/ N,
io:format("PID=~p,TotalTime=~p(~p), Avgtime= ~p (~p) usecond~n", [self(),Time1,Time2,U1, U2]),
wait().
wait() ->
receive
{testmsg,X} -> io:format("Message: ~p~n", [X])
end.
for(N, N, F) ->
[F()];
for(I, N, F) ->
[F()|for(I+1, N, F)].
-module(yqmsg).
-export([max/1,wait/0]).
max(N) ->
io:format("PID=~p,Max Message: ~p~n", [self(),N]),
statistics(runtime),
statistics(wall_clock),
L = for(1, N, fun()->self()!{testmsg,"1234567890abcdefghijklmnopqrstuvwxyz#$%^ABCDEFGHIJ"} end),
{_, Time1} = statistics(runtime),
{_, Time2} = statistics(wall_clock),
U1 = Time1 *1000/ N,
U2 = Time2 *1000/ N,
io:format("PID=~p,TotalTime=~p(~p), Avgtime= ~p (~p) usecond~n", [self(),Time1,Time2,U1, U2]),
wait().
wait() ->
receive
{testmsg,X} -> io:format("Message: ~p~n", [X])
end.
for(N, N, F) ->
[F()];
for(I, N, F) ->
[F()|for(I+1, N, F)].
查内存占用是用操作系统的命令: ps auxmm|egrep -i 'smp|RSS', 看的是vsz列的值,按运行前后的差值除以1024得到下面的结果。
当消息字符串是20个字节时,发送 1百万个消息:
每个消息CPU耗时:1.44us, 总耗时:1.601us
erl进程的内存增长:63.58M
当消息字符串是50个字节时,时间和内存消耗没变化(神奇,时间没变可以理解,为什么内存消耗也没变化,测试方法有什么问题呢?)
当消息继续改大后,内存增值连小数点后面都没变。新消息是:{testmsg,"1234567890abcdefghijklmnopqrstuvwxyz#$%^ABCDEFGHIJ",9999999,999999.99,1234567890123,eeooff}
当消息字符串是50个字节时,发送 1千万个消息:
每个消息CPU耗时:2.058us, 总耗时:2.3032us
erl进程的内存增长:647.9688M
当消息字符串是50个字节时,发送 10万个消息:
每个消息CPU耗时:多次测试,大约在0.6~0.9 us, 总耗时:0.7~1.1 us
erl进程的内存增长:多次测试,结果分别为 8.79M,8.94M,4.02M,5.02M
测试环境说明:
PC Server,CPU是 2G主频,操作系统是安装在vmware虚拟机上,RedHat 2.6.18-164.el5 #1 SMP。
总结:
做架构设计时,基本上可以按每个消息 1us 的性能来考虑,而且在消息数量百倍增长的情况下,性能下降约3倍,很强大。
测试中,每个消息占据的内存大小跟消息本身居然没有关系,实在想不通啊。
测试仅是自己给自己发消息,没测试很多个进程,相互间发消息的情况,这个代码暂时还不知道怎么写。
- erlang进程间发送消息的性能
- erlang 进程消息及ets性能测试
- erlang的消息发送和接收
- 进程间的通信以及发送消息
- erlang多进程间通信的性能测试
- PostThreadMessage发送进程间消息
- 发送WM_COPYDATA消息实现进程间的通信
- erlang 进程消息和状态
- erlang进程性能分析方法
- 进程间发送消息整理(简易方案)
- 进程间发送消息整理(高级方案)
- erlang的消息队列
- erlang 消息发送 gen_server:call cast info
- 进程间传递消息(发送和接收系统消息)
- erlang 进程的 hibernate
- erlang的进程池
- erlang性能分析及进程监控工具
- [Erlang]进程结构和性能分析
- myeclipse 引入jar包 (包括 jdbc 驱动引用)
- 常用的android弹出对话框
- flex4 画线上带点的效果
- QT/X11在Red Hat9.0上的安装
- 在CentOS中设置时间同步的方法
- erlang进程间发送消息的性能
- 更改zend studio 的web浏览器 让zend studio 不再使用内部web浏览器
- 曲线拟合的最小二乘法
- OLE剪切板学习
- 浅谈Active控件的CAB制作包
- CentOS6 图形界面(gnome)安装
- 常见英语面试问题集锦
- Eclipse 插件手动安装
- public class Assemble<T> where T:new()