2017-09-27 6 views
0

この質問は、値がio_listであるかどうかを調べる方法と同じですと思います。これを可能な限り効率的にしたいので、io_listであるかどうかをチェックするプロセスの一部として値をバイナリに変換したくないのです。エリクシール(またはエルラン)の値がバイナリとして書くことができるかどうかをテストする方法

+0

私はこれをチェックするすべての機能がないと思うが、私は値にiolist_size/'1'を呼び出すと 'ArgumentError'はかなり高速である必要があり引くと信じています。 ArgumentErrorが発生した場合、それは有効なアイリストではありません。 – Dogbert

+2

あなたが何をしていても、io_listであるかどうかをチェックするには、システムは(可能な)io_listのすべての要素を反復処理する必要があります。自分のプログラムがどのようなデータを生成したのか決して知るべきではありません。信頼できないソースからのコードの場合は、*とにかくそれを検証し、その時点から知っておく必要があります。実際の答えは、実行時のチェックではなく、コンパイル時にDialyzerを使用することです。 – zxq9

答えて

1

Erlangのstdlibを閲覧した後で、:erlang.iolist_sizeを使用し、ArgumentErrorをキャッチして無効なアイリストを検出することをお勧めします。

iolist? = fn x -> 
    try do 
    :erlang.iolist_size(x) 
    true 
    rescue 
    ArgumentError -> false 
    end 
end 

IO.inspect iolist?("foo") 
IO.inspect iolist?(["foo"]) 
IO.inspect iolist?(:foo) 

出力:私の非常に非科学的なベンチマークで

true 
true 
false 

が、これは約三度:erlang.iolist_to_binary/1と同じくらい速いです。

iolist = List.duplicate([[[1, "2"], '3'], ?4], 1000000) 
IO.inspect :timer.tc(:erlang, :iolist_to_binary, [iolist]) 
IO.inspect :timer.tc(:erlang, :iolist_size, [iolist]) 
{82291, 
<<1, 50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1, 
    50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1, 
    50, 51, 52, 1, 50, 51, 52, 1, ...>>} 
{25577, 4000000} 
関連する問題