我正在编写代码以解码来自二进制协议(protocol)的消息。每个消息类型都分配有一个1字节的类型标识符,每个消息都带有此类型ID。消息均以包含5个字段的公共(public) header 开头。我的API很简单:

decoder:decode(Bin :: binary()) -> my_message_type() | {error, binary()}`

我的第一个直觉是通过为每种消息类型编写一个解码函数,并在fun参数中完全解码该消息类型来充分依靠模式匹配
decode(<<Hdr1:8, ?MESSAGE_TYPE_ID_X:8, Hdr3:8, Hdr4:8, Hdr5:32,
         TypeXField1:32, TypeXFld2:32, TypeXFld3:32>>) ->
    #message_x{hdr1=Hdr1, hdr3=Hdr3 ... fld4=TypeXFld3};

decode(<<Hdr1:8, ?MESSAGE_TYPE_ID_Y:8, Hdr3:8, Hdr4:8, Hdr5:32,
         TypeYField1:32, TypeYFld2:16, TypeYFld3:4, TypeYFld4:32
         TypeYFld5:64>>) ->
    #message_y{hdr1=Hdr1, hdr3=Hdr3 ... fld5=TypeYFld5}.

请注意,尽管消息的前5个字段在结构上相同,但之后的字段随每种消息类型的不同而不同。

我大约有20种消息类型,因此有20种类似于上面的函数。我是否使用这种结构多次解码完整的消息?这是惯用的吗?我只对功能 header 中的消息类型字段进行解码,然后对消息正文中的完整消息进行解码,会更好吗?

最佳答案

只是同意您的风格是非常习惯的Erlang。除非您认为解码使您的代码更清晰,否则请不要将其拆分为单独的部分。有时进行这种分组可能更合乎逻辑。

编译器很聪明,并且以不会多次解码消息的方式编译模式匹配。它将首先解码前两个字段(字节),然后使用第二个字段的值(消息类型)来确定如何处理其余的消息。不管二进制文件的公共(public)部分有多长,它都可以工作。

因此,他们无需尝试通过将解码分为几个部分来“帮助”编译器,这不会使其效率更高。同样,只有在使您的代码更清晰的情况下,才执行此操作。

关于performance - Erlang模式匹配位串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5812902/

10-13 02:07