改進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
思月行云 閱讀(1344)
評論(0) 編輯 收藏 引用 所屬分類:
Erlang