我在这里涉及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解决方案)
答案 0 :(得分:6)
如果您使用的是Python 2.7或3.1及更高版本,则可以对整数使用bit_length
方法。它返回表示整数所需的位数,即比最高位的索引多一个:
>>> (1).bit_length()
1
>>> (4).bit_length()
3
>>> (32).bit_length()
6
这可能是最恐怖的解决方案,因为它是标准库的一部分。如果您发现dict
表现更好并且这是性能瓶颈,我认为没有理由不使用它。