作为练习,我正在并行实现Eratosthenes筛网。作为其一部分,我实现了一个位图序列,每个数字使用一位以节省内存。一次读取一位看起来不错,但是设置它们很慢,尤其是当我使用大型二进制文件时。
getBit(Bin, N, Size)->
R=Size-N-1,
<<_:N,Bit:1,_:R>> = Bin,
Bit.
setBit(Bin, N, Size)->
R=Size-N-1,
<<A:N,_:1,B:R>> = Bin,
<<A:N,1:1,B:R>>.
有没有一种方法可以在功能良好的Erlang中做到这一点,也许类似于Arrays的工作方式?
我已经阅读了关于hipe_bifs:bytearray_update的内容,但希望保持我的编码风格正常运行。
最佳答案
您可以将位图存储为整数(如果它们的长度不超过1000位):
-module(z).
-export([get_bit/2, set_bit/2]).
get_bit(N, B) -> N band bit_to_int(B) > 0.
set_bit(N, B) -> N bor bit_to_int(B).
bit_to_int(B) -> 1 bsl B.
您可以尝试不带大小和填充至字节的版本:
getBit(Bin, N)->
<<_:N/bitstring,Bit:1,_/bitstring>> = Bin,
Bit.
setBit(Bin, N)->
<<A:N,_:1,B/bitstring>> = Bin,
<<A:N,1:1,B>>.
%OR:
setBit(Bin, N)->
PSize = 8 - ((N + 1) rem 8),
<<A:N,_:1, Pad:PSize,B/bytes>> = Bin,
<<A:N,1:1,Pad:PSize,B>>.
可能是好是坏:-)
关于functional-programming - 如何在Erlang二进制文件中一次高效地设置一位而不用强制执行?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1994395/