下面是添加二进制字节的简单实现。根据eprof它很慢(大约占总时间的10% - 主要是因为许多人调用了binary:part/3
)。
如何优化?
calc_checksum(Packet) when is_binary(Packet)->
calc_checksum(Packet, 0).
calc_checksum(<<>>, Acc) ->
Acc band 16#FFFF;
calc_checksum(Packet, Acc) when is_binary(Packet) ->
W = binary:decode_unsigned(binary:part(Packet, 0, 2), little),
NextAcc = Acc + W,
NextBytes = binary:part(Packet, byte_size(Packet), -(byte_size(Packet)-2)),
calc_checksum(NextBytes, NextAcc).
答案 0 :(得分:8)
更优雅的解决方案是:
calc_checksum(<<W:16/little,Rest/bytes>>, Acc0) ->
Acc1 = Acc0 + W,
calc_checksum(Rest, Acc1);
calc_checksum(<<>>, Acc) -> Acc band 16#FFFF.
如果二进制包含奇数个字节,则此代码将生成错误。使用模式匹配通常可以提供更优雅的代码。
答案 1 :(得分:2)
在binary
中使用模式匹配而不是调用函数似乎使我在shell中尝试的伪基准测试的速度加倍。像这样:
calc_checksum(Packet, Acc) when is_binary(Packet) ->
<<W:16/little, NextBytes/binary>> = Packet,
NextAcc = Acc + W,
calc_checksum(NextBytes, NextAcc).
(我可能错了,但是如果你将NextAcc
设置为(Acc + W) band 16#FFFF
,你应该得到相同的结果,如果你在非常大的二进制文件上运行它,应该避免使用bignums。)
答案 2 :(得分:2)