开发者

Binary operations on Erlang binaries?

开发者 https://www.devze.com 2022-12-14 17:53 出处:网络
What\'s best way to do the following? Binary -> list ->开发者_如何学C binary seems unnecessary.

What's best way to do the following? Binary -> list ->开发者_如何学C binary seems unnecessary.

binary_and(A, B) ->
    A2 = binary_to_list(A),
    B2 = binary_to_list(B),
    list_to_binary([U band V || {U, V} <- lists:zip(A2, B2)]).


If don't care of performance, your code is absolutely OK. Otherwise you can do something different.

For example Erlang supports Integers of arbitrary size:

binary_and(A, B) ->
  Size = bit_size(A),
  <<X:Size>> = A,
  <<Y:Size>> = B,
  <<(X band Y):Size>>.

Or you can handcraft your own binary zip routine:

binary_and(A,B) -> binary_and(A, B, <<>>).

binary_and(<<A:8, RestA/bytes>>, <<B:8, RestB/bytes>>, Acc) ->
  binary_add(RestA, RestB, <<Acc/bytes, (A band B):8>>);
binary_and(<<>>, <<>>, Result) -> Result.

Or optimized version:

binary_and(A,B) -> binary_and(A, B, <<>>).

binary_and(<<A:64, RestA/bytes>>, <<B:64, RestB/bytes>>, Acc) ->
  binary_add(RestA, RestB, <<Acc/bytes, (A band B):64>>);
binary_and(<<A:8, RestA/bytes>>, <<B:8, RestB/bytes>>, Acc) ->
  binary_add(RestA, RestB, <<Acc/bytes, (A band B):8>>);
binary_and(<<>>, <<>>, Result) -> Result.

or more sophisticated

binary_and(A,B) -> binary_and({A, B}, 0, <<>>).

binary_and(Bins, Index, Acc) ->
  case Bins of
    {<<_:Index/bytes, A:64, _/bytes>>, <<_:Index/bytes, B:64, _/bytes>>} ->
      binary_add(Bins, Index+8, <<Acc/bytes, (A band B):64>>);
    {<<_:Index/bytes, A:8, _/bytes>>, <<_:Index/bytes, B:8, _/bytes>>} ->
      binary_add(Bins, Index+1, <<Acc/bytes, (A band B):8>>);
    {<<_:Index/bytes>>, <<_:Index/bytes>>} -> Acc
  end.

Anyway you have to measure if you are really interested in performance. May be the first one is the fastest for your purposes.


If you want to see the power of the dark side...

binary_and(A, B) ->
  Size = erlang:byte_size(A),
  Size = erlang:byte_size(B),
  Res = hipe_bifs:bytearray(Size, 0),
  binary_and(Res, A, B, 0, Size).

binary_and(Res, _A, _B, Size, Size) ->
  Res.

binary_and(Res, A, B, N, Size) ->
  Bin = hipe_bifs:bytearray_sub(A, N) band hipe_bifs:bytearray_sub(B,N),
  hipe_bifs:bytearray_update(Res, N, Bin),
  binary_and(Res, A, B, N+1, Size).
0

精彩评论

暂无评论...
验证码 换一张
取 消