【问题标题】:Erlang: split binary on every charErlang:在每个字符上拆分二进制文件
【发布时间】:2017-05-26 22:38:23
【问题描述】:

我写了一个有效的函数,将二进制文件拆分为每个字符,但我觉得有一种更简单的方法:

my_binary_to_list(<<H,T/binary>>) ->
%slightly modified version of http://erlang.org/doc/efficiency_guide/binaryhandling.html
    [list_to_binary([H])|my_binary_to_list(T)];
my_binary_to_list(<<>>) -> [].

> my_binary_to_list(<<"ABC">>).
[<<"A">>,<<"B">>,<<"C">>]

我认为这可能是因为list_to_binary([H]) 而导致混乱,因为H 应该已经是二进制文件。

我尝试直接使用该链接函数,但得到了"AA",这不是我想要的。然后我尝试了[H],得到了["A","B","C"],这也不是我想要的。

【问题讨论】:

    标签: erlang


    【解决方案1】:

    您可以从单个字节创建二进制文件,而无需创建列表并像这样调用list_to_binary

    my_binary_to_list(<<H,T/binary>>) ->
        [<<H>>|my_binary_to_list(T)];
    

    您也可以在这里使用二进制推导在一行中执行与上述相同的逻辑:

    1> [<<X>> || <<X>> <= <<"ABC">>].
    [<<"A">>,<<"B">>,<<"C">>]
    

    您也可以直接提取大小为 1 的二进制文件(不过这可能不会比上面更快):

    2> [X || <<X:1/binary>> <= <<"ABC">>].
    [<<"A">>,<<"B">>,<<"C">>]
    

    编辑:使用timer:tc/1 的快速工作台运行第二个代码的时间大约是第一个代码的一半,但出于性能原因,您应该在使用任何一个代码之前对自己进行基准测试。也许第二个是通过创建子二进制文件来共享大型二进制文件?

    1> Bin = binary:copy(<<"?">>, 1000000).
    <<"????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"...>>
    2> timer:tc(fun() -> [<<X>> || <<X>> <= Bin] end).
    {14345634,
     [<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
      <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
      <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
      <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<...>>|...]}
    3> timer:tc(fun() -> [X || <<X:1/binary>> <= Bin] end).
    {7374003,
     [<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
      <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
      <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
      <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<...>>|...]}
    

    【讨论】:

    • 嗯,这在我的基准测试中似乎也更快,谢谢!
    【解决方案2】:

    您可以将列表推导式与位字符串生成器一起使用(&lt;= 使用二进制文件,而 &lt;- 使用列表):

    > [<<A>> || <<A>> <= <<"foo">>].
    [<<"f">>,<<"o">>,<<"o">>]
    

    在您的版本中,list_to_binary([H]) 可以替换为 &lt;&lt;H&gt;&gt; - 两者都生成包含一个字节的二进制文件。使用列表推导式而不是递归函数是否“更容易”可能是个人喜好问题。

    【讨论】:

      猜你喜欢
      • 2015-06-10
      • 1970-01-01
      • 2015-06-01
      • 2010-09-30
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-22
      相关资源
      最近更新 更多