2011-03-07 83 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). 
相關問題