How to efficiently set one bit at a time in Erlang binary format without need?

As an exercise, I am working on a parallel implementation of the Eratosthenes sieve. As part of this, I implement a sequence of bitmaps using one bit per number to save memory. Reading bits in turn seems fine, but setting them up is slow, especially when I use large binaries.

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>>.

Is there a way to do this well in functional Erlang, perhaps similar to how arrays work? I read about hipe_bifs: bytearray_update, but would prefer my coding style to be functional.

+3
source share
2 answers

( ~ 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>>.

: -)

+3

, O(log(n)) get set, Erlang . O(log(n)) . array, dict, gb_trees gb_sets .

, , : hipe_bifs , ets.

+2

Source: https://habr.com/ru/post/1727137/


All Articles