2011-03-07 86 views
3

我通过查询字符串将BERT传递给Erlang。我使用http_bin选项通过gen_tcp读取它,所以它像这样到达< <“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”>>)。如何在BERT为二进制字符串时解码BERT

我可以像这样解析它到正确的形式。但是这似乎令人费解,并且比我希望的要慢(约5k /秒,每个200字节)。还想出了一些基于io_lib:fread/2的东西,但它并没有多好,仍然看起来很尴尬。

  1. 是否有BIF或NIF可能会这样做?

  2. 如果不是,有没有更好的方法来做到上述加速?

+6

这只是让我觉得事情幢楼的查询字符串被打破。我建议使用类似base64的东西来编码BERT查询字符串的使用。 – 2011-03-07 21:44:37

+1

是的,用逗号分隔整数发送二进制字符串不是很有效或可分析。 (因为你的论据有效,如果可以的话,使用[Erlang'base64'库](http://www.erlang.org/doc/man/base64.html)) – 2011-03-07 22:44:32

+2

其次。看来你的客户发送了一个无效的BERT请求。 – hdima 2011-03-07 22:52:29

回答

0

对于它的价值,另一种解决方案 - 推测慢,但可能不太特设,依口味 - 是看它的解析二郎的一个子集,其工具存在的问题:

parse(Source) -> 
    case erl_scan:string(Source++" .") of 
    {ok, Tokens, _} -> 
     case erl_parse:parse_term(Tokens) of 
     {ok, Bin} when is_binary(Bin) -> % Only accept binary literals. 
      Bin; 
     _ -> error(badarg) 
     end; 
    _ -> error(badarg) 
    end. 

在这种情况下可能是过度的,但没有比原来的解决方案更多的代码。

0

使用此代码,你可以在本地(HIPE)解析可达75MB/s和高达17MB/s的字节代码:

-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). 
相关问题