Как декодировать BERT, когда BERT - двоичная строка - PullRequest
3 голосов
/ 08 марта 2011

У меня есть BERT , переданный Эрлангу через строку запроса.Я читаю его через gen_tcp с опцией http_bin, поэтому он приходит примерно так << "131,104,1,100,0,2,104,105" >>.Что только почти правильно, потому что я хочу декодировать его с помощью binary_to_term / 2.Но binary_to_term / 2 хочет двоичный двоичный файл, а не строковый двоичный файл (он хочет << 131,104,1,100,0,2,104,105 >> не << "131,104,1,100,0,2,104,105" >>).

Iможно разобрать его в нужную форму следующим образом.

parse(Source) ->
    Bins = binary:split(Source, <<",">>, [global]),
    parse(Bins, []).
parse([H | T], Acc) ->
    parse(T, [list_to_integer(binary_to_list(H)) | Acc]);
parse([], Acc) ->
    list_to_binary(lists:reverse(Acc)).

Но это кажется запутанным и медленнее, чем я ожидал (~ 5k / sec с каждым из 200 байтов).Также придумали что-то, основанное на io_lib: fread / 2, но это было не намного лучше и все еще выглядит неловко.

  1. Есть ли где-нибудь BIF или NIF, которые могли бы сделать это?

  2. Если нет, то есть ли лучший способ сделать это, чтобы ускорить его?

Ответы [ 2 ]

0 голосов
/ 27 марта 2012

Используя этот код, вы можете анализировать до 75 МБ / с в нативном (HiPE) и до 17 МБ / с в байт-коде:

-module(str_to_bin).

-export([str_to_bin/1]).

str_to_bin(Bin) when is_binary(Bin) ->
  str_to_bin(Bin, <<>>).

-define(D(X), X >= $0, X =< $9 ).

-define(C(X), (X band 2#1111)).

str_to_bin(<<X,Y,Z,Rest/binary>>, Acc)
    when ?D(X), ?D(Y), ?D(Z) ->
  str_to_bin_(Rest, <<Acc/binary, (?C(X)*100 + ?C(Y)*10 + ?C(Z))>>);
str_to_bin(<<Y,Z,Rest/binary>>, Acc)
    when ?D(Y), ?D(Z) ->
  str_to_bin_(Rest, <<Acc/binary, (?C(Y)*10 + ?C(Z))>>);
str_to_bin(<<Z,Rest/binary>>, Acc)
    when ?D(Z) ->
  str_to_bin_(Rest, <<Acc/binary, ?C(Z)>>).

-compile({inline, [str_to_bin_/2]}).

str_to_bin_(<<>>, Acc) -> Acc;
str_to_bin_(<<$,, Rest/binary>>, Acc) -> str_to_bin(Rest, Acc).
0 голосов
/ 27 марта 2012

Для чего бы то ни было, альтернативное решение - предположительно более медленное, но, возможно, менее специализированное, в зависимости от вкуса - это рассматривать его как проблему анализа подмножества Erlang, для которого существуют инструменты:1002 *

Возможно, излишнее в этом контексте, но не больше кода, чем в исходном решении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...