DEV Community

voluntas
voluntas

Posted on

Erlang/OTP で <<15,254>> を <<"0FFE">> にする方法

もう、何度も作っててツラくなってきた。早く標準ライブラリとして実装して欲しい。

今後皆が使うべき実装

<< <<if X < 10 -> X + $0; true -> X - 10 + $A end>> || <<X:4>> <= <<0,1,253,255>> >>.
Enter fullscreen mode Exit fullscreen mode

よく使ってた実装

> list_to_binary([ io_lib:format("~2.16.0B", [X]) || <<X:8>> <= <<0,1,254,255>> ]).
<<"0001FEFF">>
Enter fullscreen mode Exit fullscreen mode
-spec hexlify(binary()) -> binary().
hexlify(Binary) ->
    list_to_binary([ io_lib:format("~2.16.0B", [X]) || <<X:8>> <= Binary ]).
Enter fullscreen mode Exit fullscreen mode

もっとシンプルで早い方法があれば是非教えて欲しい。

皆様の実装

https://twitter.com/k0u_chang/status/600686773279199232

> << <<if X < 10 -> X + $0; true -> X - 10 + $A end>> || <<X:4>> <= <<0,1,253,255>> >>.
<<"0001FDFF">>
Enter fullscreen mode Exit fullscreen mode

https://twitter.com/hio/status/600690978287013888

> << <<(X + if X < 10 -> $0; true -> $A - 10 end)>> || <<X:4>> <= <<0,1,254,255>> >>.
<<"0001FEFF">>
Enter fullscreen mode Exit fullscreen mode

https://gist.github.com/sile/c8df7cc9a106c7d86039

コンパイルをすると ...

測定大会

環境

Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Enter fullscreen mode Exit fullscreen mode
> timer:tc(fun() -> list_to_binary([ io_lib:format("~2.16.0B", [X]) || <<X:8>> <= list_to_binary(lists:seq(0,255)) ]) end).
{3486,
 <<"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435"...>>}
> timer:tc(fun() -> << <<if X < 10 -> X + $0; true -> X - 10 + $A end>> || <<X:4>> <= list_to_binary(lists:seq(0,255)) >> end).
{6650,
 <<"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435"...>>}
> timer:tc(fun() -> << <<(X + if X < 10 -> $0; true -> $A - 10 end)>> || <<X:4>> <= list_to_binary(lists:seq(0,255)) >> end).
{9026,
 <<"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435"...>>}
Enter fullscreen mode Exit fullscreen mode

https://gist.github.com/sile/c8df7cc9a106c7d86039

実行は提案者の環境

> timer:tc(fun() -> hexlify:hex1(list_to_binary(lists:seq(0,255))) end).                                                                   
{220,
 <<"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435"...>>}

> timer:tc(fun() -> hexlify:hex2(list_to_binary(lists:seq(0,255))) end).
{36,
 <<"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435"...>>}
Enter fullscreen mode Exit fullscreen mode
-module(hexlify).

-export([hex1/1, hex2/1]).

hex1(Bin) ->
  list_to_binary([ io_lib:format("~2.16.0B", [X]) || <<X:8>> <= Bin ]).

hex2(Bin) ->
  << <<if X < 10 -> X + $0; true -> X - 10 + $A end>> || <<X:4>> <= Bin >>.
Enter fullscreen mode Exit fullscreen mode

Top comments (0)