胶合二进制文件有多贵(list_to_binary)?

时间:2009-09-09 04:46:43

标签: erlang binary list

一个进程在异步套接字上侦听服务器,并在每条消息上{tcp,Socket,Bin}获取缓冲区并且:

Data = list_to_binary([Buffer, Bin]),
    {next_state, 'READY', State#state{buffer = Data}}.

在某些事件中,它会刷新缓冲区:

'READY'({flush}, #state{buffer = Buffer} = State) ->
    {reply, {Buffer}, 'READY', State#state{buffer = <<>>}}.

贵吗?也许更好的只是制作一个列表并在刷新时使list_to_binary(lists:reverse())一次?

2 个答案:

答案 0 :(得分:2)

您的第一种方法似乎 比第二种方法慢(在我的平台上大约为3000):

-module(test).
-export([test/0, performance_test/4]).

-define(ITERATIONS, 100000).
-define(NEW_DATA, <<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>).

accumulate_1(AccumulatedData, NewData) ->
  list_to_binary([AccumulatedData, NewData]).

extract_1(AccumulatedData) ->
  AccumulatedData.

accumulate_2(AccumulatedData, NewData) ->
  [NewData | AccumulatedData].

extract_2(AccumulatedData) ->
  list_to_binary(lists:reverse(AccumulatedData)).

performance_test(AccumulateFun, ExtractFun) ->
  {Time, _Result} = timer:tc(test, performance_test, [AccumulateFun, ExtractFun, [], ?ITERATIONS]),
  io:format("Test run: ~p microseconds~n", [Time]).

performance_test(_AccumulateFun, ExtractFun, AccumulatedData, _MoreIterations = 0) ->
  ExtractFun(AccumulatedData);

performance_test(AccumulateFun, ExtractFun, AccumulatedData, MoreIterations) ->
  NewAccumulatedData = AccumulateFun(AccumulatedData, ?NEW_DATA),
  performance_test(AccumulateFun, ExtractFun, NewAccumulatedData, MoreIterations - 1).

test() ->
  performance_test(fun accumulate_1/2, fun extract_1/1),
  performance_test(fun accumulate_2/2, fun extract_2/1),
  ok.

输出:

7> test:test().
Test run: 57204314 microseconds
Test run: 18996 microseconds

答案 1 :(得分:2)

在当前版本中,仿真器对二进制文件的处理得到了显着改善, 所以现在你也可以采用更简单的路径并按块生成二进制块:

buffer = #state{buffer = <<Buffer/binary, Bin/binary>>}

我没有对其他方法进行测试,但不应该坏。 不同实现之间的性能也可能取决于您在同一缓冲区执行此操作的次数以及每个块的大小。