2009-12-17 52 views
5

Cách tốt nhất để thực hiện những điều sau đây là gì? Nhị phân -> danh sách -> nhị phân có vẻ không cần thiết.Hoạt động nhị phân trên tệp nhị phân Erlang?

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)]). 
+2

Sử dụng các tùy chọn 'bin_opt_info' khi biên soạn để có được một số gợi ý về tối ưu hóa việc sử dụng hệ nhị phân. Xem hướng dẫn biên dịch để biết chi tiết. – Zed

Trả lời

3

Nếu không quan tâm đến hiệu suất, mã của bạn hoàn toàn OK. Nếu không, bạn có thể làm điều gì đó khác.

Ví dụ Erlang hỗ trợ Số nguyên kích thước tùy ý:

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

Hoặc bạn có thể thủ công thường xuyên zip nhị phân của riêng bạn:

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. 

Hoặc tối ưu hóa phiên bản:

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. 

trở lên tinh vi

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. 

Dù sao, bạn phải đo lường xem bạn có thực sự quan tâm đến hiệu suất hay không. Có thể là người đầu tiên nhanh nhất cho mục đích của bạn.

3

Nếu bạn muốn xem sức mạnh của mặt tối ...

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).