使用Python和numpy,什么是一种快速有效的处理大位域的方法?

2024-09-30 10:33:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用小型&;Python中的快速大位域,理想情况下除了numpy之外没有依赖项或很少依赖项。我希望的操作大致相当于:

bits = new_bitfield(3000000)  # 3 million bits
bits.set_bit(n, 1)
bits.set_bit(n, 0)
bits.get_bit(n)

我希望bits的底层存储非常精简/低开销。(理想情况下,bits对象的宽度仅超过366.21千字节。)

我希望GET和SET的速度非常快,类型检查/类型强制开销最小——可能在使用Cython或Numba特定代码(或它们各自的内联选项)时速度特别快

在保持尽可能完美的外观的同时,达到C级速度/紧凑度的最佳方式是什么


Tags: numpy类型newgetbit情况速度bits
1条回答
网友
1楼 · 发布于 2024-09-30 10:33:29

自己开发应该不会太难,另一个选择是使用现有的实现。不管是好是坏,std::vector<bool>正是您想要的:它每个值只使用1位(因此bool-template参数有点误导,因为bool至少有1个字节长)

使用Cython,它可能看起来像这样(编译为c++扩展):

%%cython -+
from libcpp.vector cimport vector
from libcpp cimport bool

cdef class Bitset:
    cdef vector[bool] bset;
    
    def __cinit__(self, size_t size):
        self.bset.resize(size, False);
        
    cpdef void set_bit(self, size_t pos, bint val) except *:        
        # self.bset[pos] = val would not check out of range
        # self.bset.at(pos) = val doesn't work with Cython
        if pos < self.bset.size():
            self.bset[pos] = val;
        else:
            raise IndexError("out of range access")    
            
    cpdef bint get_bit(self, size_t pos):
        return self.bset.at(pos)

可以用作

mybitset = Bitset(10)
mybitset.set_bit(2, True)
mybitset.get_bit(1), mybitset.get_bit(2) #returns (False, True)

mybitset.set_bit(11, True) #throws
mybitset.get_bit(12, True) #throws

抛出,不要以未定义的行为结束

显然,为了将开销保持在最低限度,使用Bitset-cdef类的代码也应该用Cython编写,因此,可以使用接口的cdef-部分,而不需要转换为Python对象,这是接口的Python部分所需要的(如上所示)

相关问题 更多 >

    热门问题