获取纯python中的标记位索引

时间:2012-08-05 16:48:02

标签: python

我在这里涉及2个问题:一个用于'如何',第二个用于'这个伟大的解决方案听起来不错吗?'
事情是这样的:我有一个int值的对象,它存储了使用该对象的所有人ID。它是使用标记技术完成的(人员ID是0-10)。

我遇到的情况是,如果这个值只标记了一个id,我想得到这个id。

对于第一次测试我使用value & (value-1)这很好,但至于第二件事,我开始想知道最好的方法是什么(我想知道它的原因是因为这个计算至少发生了在关键位置每秒300次)。

所以我想到的第一种方式是使用math.log(x,2),但我觉得这个解决方案有点不舒服,因为它涉及一个值的“硬”数学,而不是非常简单的位操作,我觉得我我错过了什么。

我想到的第二种方法是计算value<<1直到它达到1,但正如你在基准测试中看到的那样,它更糟糕。

我实现的第三种方式是非计算方式,并且是最快的,它使用的字典包含0-10的所有可能值。

就像我之前说过的那样:在 python中有没有“正确”的方法呢? 基于字典的解决方案是一种“合法”的解决方案吗? (可读性/任何其他原因 - 为什么不能?)

import math
import time

def find_bit_using_loop(num,_):
    c=0
    while num!=1:
        c+=1
        num=num>>1
    return c

def find_bit_using_dict(num,_):
    return options[num]

def get_bit_idx(num, func):
    t=time.time()
    for i in xrange(100000):
        a=func(num,2)
    t=time.time()-t
    #print a
    return t

options={}
for i in xrange(20):
    options[1<<i]=i

num=256
print "time using log:", get_bit_idx(num, math.log)
print "time using loop:", get_bit_idx(num, find_bit_using_loop)
print "time using dict:", get_bit_idx(num, find_bit_using_dict)

输出:

time using log: 0.0450000762939
time using loop: 0.156999826431
time using dict: 0.0199999809265

(这里有一个非常相似的问题:return index of least significant bit in Python,但首先,在这种情况下我知道只有1个标记位,其次,我想保持它纯粹的python解决方案)

1 个答案:

答案 0 :(得分:6)

如果您使用的是Python 2.7或3.1及更高版本,则可以对整数使用bit_length方法。它返回表示整数所需的位数,即比最高位的索引多一个:

>>> (1).bit_length()
1
>>> (4).bit_length()
3
>>> (32).bit_length()
6

这可能是最恐怖的解决方案,因为它是标准库的一部分。如果您发现dict表现更好并且这是性能瓶颈,我认为没有理由不使用它。