functional-programming - 如何在 Erlang 二进制文件中一次高效地设置一位而不需要命令式?

标签 functional-programming erlang arrays

作为一项练习,我正在研究埃拉托斯特尼筛法的并行实现。作为其中的一部分,我正在实现一系列位图,每个数字使用一位来节省内存。一次读取一位似乎工作正常,但设置它们很慢,尤其是当我使用大型二进制文件时。

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 中很好地做到这一点,也许类似于数组的工作方式? 我已经阅读过有关 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.
<小时/>

您可以尝试不传递 Size 并填充到字节的版本:

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/

相关文章:

erlang - 如何获得棘手的函数引用?

file - Erlang 在文件 :write_file(Filename, 数据上生成错误,[附加])

java - 数组和错误打印

java - 通用数组上的二分搜索返回前两个索引或 Stackoverflow 异常

erlang - 什么是 Erlang 节点?

c - long int 数组导致错误 : subscripted value is neither array nor pointer nor vector

scala - 在Scala中将方法提取到独立函数

python - 如何为 Python Pandas 数据框创建灵活的命令过滤器

c# - 如何支持名义类型语言的结构类型?

javascript - 在 Javascript 中映射一组任务