Erlang中日志管理三两话
日志系统的重要性就不罗嗦了,直接开始吧。
一、基本概念
在Erlang中,通过两个概念管理错误事情:事件管理器(event manager)和事件处理句柄(event handles)。通常各种错误、警告和消息事件都会有Erlang运行时系统发送给事件管理器。在Erlang中,默认的事情管理器为error logger,其进程名注册为error_logger。默认情况下error_logger把这些事件直接输出到控制台上。 继续阅读 »
日志系统的重要性就不罗嗦了,直接开始吧。
一、基本概念
在Erlang中,通过两个概念管理错误事情:事件管理器(event manager)和事件处理句柄(event handles)。通常各种错误、警告和消息事件都会有Erlang运行时系统发送给事件管理器。在Erlang中,默认的事情管理器为error logger,其进程名注册为error_logger。默认情况下error_logger把这些事件直接输出到控制台上。 继续阅读 »
QQ群:PHP内核与扩展研究 48448818
PHP内核与扩展研究。加群请说明自己感兴趣领域或者擅长领域!否则一律不予通过,请谅
可以使用List comprehensions时不要 使用map或者filter,简单的性能测试对比一下:
第一组,map和list comprehensions对比,代码如下:
%%map方式
-module(map_test).
-export([start/1]).
start(N) ->
statistics(runtime),
erlang:statistics(wall_clock),
lists:map(fun (X) -> X*X end, lists:seq(1, N)),
{_, T1} = erlang:statistics(runtime),
{_, T2} = erlang:statistics(wall_clock),
io:format("total times: ~p, load time: ~p (~p)", [N, T1, T2]).
%%list comprehensions方式
-module(list_comp_test).
-export([start/1]).
start(N) ->
statistics(runtime),
erlang:statistics(wall_clock),
[X*X || X <- lists:seq(1, N)],
{_, T1} = erlang:statistics(runtime),
{_, T2} = erlang:statistics(wall_clock),
io:format("total times: ~p, load time: ~p (~p)", [N, T1, T2]).
测试N为1000000时结果对比:

结果取得是平均值,可以很明显的看出comprehension方式性能要高。
关于filter,则类似。不再作测试。
即日起使用新的域名 www.qingliangcn.com,原有域名保留一定时间。
虎年好运,新春愉快!
这段时间我们的项目遇到广播包的一些性能问题,想起之前看到yufeng老大提到的1s广播40K包的问题,我也想测试测试我们机器的IO能力。
这次仅仅测试发包的能力,采用的是一对一的方式。
测试代码: 继续阅读 »
erlang的bif中自带了md5计算函数,但是结果却是二进制的,即使转成list,也是10进制表示,google了一下得到一段代码用于获得字符串形式的md5结果(16位):
md5(S) ->
Md5_bin = erlang:md5(S),
Md5_list = binary_to_list(Md5_bin),
lists:flatten(list_to_hex(Md5_list)).
list_to_hex(L) ->
lists:map(fun(X) -> int_to_hex(X) end, L).
int_to_hex(N) when N < 256 ->
[hex(N div 16), hex(N rem 16)].
hex(N) when N < 10 ->
$0+N;
hex(N) when N >= 10, N < 16 ->
$a + (N-10).
英文链接 http://sacharya.com/md5-in-erlang/
开始时用的传统思路(循环读取):
recv(ClientSock, PacketLenOld, Remain)
when is_integer(PacketLenOld) and is_binary(Remain) ->
case gen_tcp:recv(ClientSock, 0) of
{ok, B} ->
Bin = <<Remain/binary, B/binary>>,
%% read the packet length
if PacketLenOld =:= 0 andalso erlang:byte_size(Bin) > 2
-> <<PacketLen:16, Remain2/binary>> = Bin;
true -> Remain2 = Bin, PacketLen = PacketLenOld
end,
?DEBUG("packet length ~p", [PacketLen]),
if
erlang:byte_size(Remain2) >= PacketLen
-> {RealData, Next} = split_binary(Remain2, PacketLen),
MainData = decode(RealData),
{ok, MainData, 0, Next};
true -> {continue, PacketLen, Remain2}
end;
{error, closed} ->
?DEBUG("socket closed ~p ~n", [ClientSock]),
{error, closed};
{error, Reason} ->
?ERROR_MSG("socket closed ~p with reason: ~p ~n", [ClientSock, Reason]),
{error, Reason}
end.
翻了翻文档发现实际上在erlang中没有必要这样麻烦
The Length argument is only meaningful when the socket is in
raw mode and denotes the number of bytes to read.
If Length = 0, all available bytes are returned.
If Length > 0, exactly Length bytes are returned, or an error;
recv(ClientSock) ->
case gen_tcp:recv(ClientSock, 2) of
{ok, PacketLenBin} -> <<PacketLen:16>> = PacketLenBin,
case gen_tcp:recv(ClientSock, PacketLen) of
{ok, RealData} ->
?DEBUG("recv data ~p", [RealData]),
{ok, decode(RealData)};
{error, Reason} ->
?ERROR_MSG("read packet data failed with reason: ~p", [Reason]),
{error, Reason}
end;
{error, Reason} ->
?ERROR_MSG("read packet length failed with reason: ~p", [Reason]),
{error, Reason}
end.