改进protobuf
改进调用方法
原来调用比较别扭,每个协议都是不同的方法名:
- encode() ->
- Person = #person{age=25, name="John"},
- test_pb:encode_person(Person).
-
- decode() ->
- Data = encode(),
- test_pb:decode_person(Data).
现在改成了统一的方法名:
- encode() ->
- Person = #person{age=25, name="John"},
- test_pb:encode(Person). %% 或者 test_pb:encode(person, Person)
-
- decode() ->
- Data = encode(),
- test_pb:decode(person, Data).
这样,很方便代码整合,只要协议映射好,封包解包就可以统一在网关层处理。
改进空协议
- 2> test_pb:encode_tos(#tos{}).
- <<>>
- 3> c(test_pb).
- src/test_pb.erl:33: Warning: variable 'Record' is unused
- {ok,test_pb}
改进调用效率
改进了序列化和反序列化的效率,encode测试效率提升10 ~ 20%, decode测试效率提升10% ~ 40%
decode优化较大,实际有些情况不止40%,取均值,部分代码优化到协议编译期,所以调用就省事多了。
获取record名字
- [RecName | _] = tuple_to_list(Data)
- 改成了:
- erlang:element(1,Data)
函数参数匹配优化
- test(Bytes) when is_binary(Bytes) ->
- ok.
- 改成了
- test(<<Bytes/binary>>) ->
- ok.
当匹配类型多时就会明显,guard模块对于多参数或多类型匹配尤为不利,erlang在编译期不能做优化。
分割二进制
- Bytes = list_to_binary("0123456789"),
- split_binary(Bytes, 3),
-
- <<B1:3/binary, B2/binary>> = Bytes,%% 测试效率没erlang:split_binary/2高
- {B1, B2}.
二进制合并
- 11> A= <<>>.
- <<>>
- 12> B= <<"1333">>.
- <<"1333">>
- 15> C= <<1,3,4>>.
- <<1,3,4>>
- 16> iolist_to_binary([B,C,A]).
- <<49,51,51,51,1,3,4>>
- 17> <<B/binary,C/binary,A/binary>>.
- <<49,51,51,51,1,3,4>>
- 18> c(loop).
- {ok,loop}
- 19> loop:test().
- 1000000 loops, using time: 281ms
- 1000000 loops, using time: 94ms
case匹配优化
- case Data of
- {double, C} -> ok;
- {float, C} -> ok;
- {int, C} -> ok;
- {string, C} -> ok;
- _ -> ok
- end
-
- case Data of
- {C, double} -> ok;
- {C, float} -> ok;
- {C, int} -> ok;
- {C, string} -> ok;
- _ -> ok
- end
第一种匹配效率较高,case匹配类似函数参数匹配,固定不变的内容放匹配表达式左边
比较erlang原生的二进制转换
最后,比较 erlang:term_to_binary/1 与 erlang:binary_to_term/1 的效率
测试结果发现erlang原生的二进制转换的效率超高,但是数据没压缩,不适合直接使用。实际使用需要配合 zlib:zip/1,这个是压缩工具,可能还需要稍微优化一下
- zip(Data) ->
- Z = zlib:open(),
- Bs =
- try
- zlib:deflateInit(Z, best_speed, deflated, -15, 1, default),
- B = zlib:deflate(Z, Data, finish),
- zlib:deflateEnd(Z),
- B
- after
- zlib:close(Z)
- end,
- iolist_to_binary(Bs).
测试结果:
erlang:term_to_binary/1(配合zlib:zip/1)时间开销比 protobuf 多15%。
erlang:binary_to_term/1(配合zlib:unzip/1)时间开销差不多是 protobuf 的50%。
2015/6/11 修复字段默认值没有生效bug
2015/6/11 修复proto文件换行无法编译bug
posted on 2017-03-13 11:47
思月行云 阅读(1306)
评论(0) 编辑 收藏 引用 所属分类:
Erlang