作为练习,我正在并行实现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/

10-09 17:24