如何在 Erlang 二进制文件中一次高效地设置一位而不需要命令式?
作为练习,我正在研究埃拉托斯特尼筛法的并行实现。作为其中的一部分,我正在实现一系列位图,每个数字使用一位来节省内存。一次读取一位似乎工作正常,但设置它们很慢,特别是当我使用大型二进制文件时。
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 的内容,但更愿意保持我的编码风格正常运行。
As an exercise I am working on a parallel implementation of the Sieve of Eratosthenes. As part of that I am implementing a sequence of bitmaps, using one bit per number to save memory. Reading bits one at a time appear to work fine, but setting them 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 have read about hipe_bifs:bytearray_update but would prefer to keep my coding style functional.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以将位图存储为整数(如果它们不长于〜1000位):
您可以尝试您的版本,不传递大小,并填充到字节:
可能更好或更差:-)
You can store your bitmaps as integers (if they are not longer than ~1000 bits):
You might try your version w/o passing the Size, and padding to bytes:
Can be better or worse :-)
一般来说,对于
get
和set
操作来说,复杂度都为O(log(n))
,这是再好不过的了,因为 Erlang 是函数式的语言。您可以使用某种类型的树来归档O(log(n))
。array
、dict
、gb_trees
和gb_sets
模块执行此操作。因此,如果您需要使其尽可能快,则必须使用命令式 - 您可以尝试
hipe_bifs
模块、流程字典和ets
表。Generally one can not do it better then with complexity of
O(log(n))
for bothget
andset
operations, since Erlang is functional language. You can archiveO(log(n))
using some type of trees.array
,dict
,gb_trees
andgb_sets
modules does this.So if you need to make it as fast as possible you have to go imperative - you could try
hipe_bifs
module, process dictionary andets
tables.