【问题标题】:Why is bin(x).count('1') faster than x &= x-1?为什么 bin(x).count('1') 比 x &= x-1 快?
【发布时间】:2019-08-02 03:16:04
【问题描述】:

代码图片 => https://i.imgur.com/KZUzckt.png

此算法用于计算二进制数中设置的位数(位数等于 1)。

我认为按位运算会更快,因为将数字转换为字符串然后计算 '1' 听起来要慢得多。

def counting1(num):
    count = 0
    while num:
         num &= num-1
         count += 1
    return count   

def counting2(num):
    return bin(num).count('1')

【问题讨论】:

  • 其他人可以给出更完整的答案,但是对这样的问题的回答通常是“因为年复一年的发展和细化意味着,在几乎所有情况下,内置的类型和方法优化,通常在 C 中,以最大限度地提高效率”
  • 我的猜测是重新分配的成本确实很高,而字符串搜索 1 的成本更低。
  • 您测试的nums 有多大,他们的人口数量是多少?

标签: python string algorithm count binary


【解决方案1】:

我做了一些测试(在 Ubuntu 上Python 3.6):

import timeit

for n in [0, 1, 2, 20, 21, 22, 23, 24, 25, 26, 27, 53, 100, 500, 10**5, 10**10, 10**50]:
    assert counting_1(n) == counting_2(n)
    t1 = timeit.timeit('f(n)', 'from __main__ import counting_1 as f, n')
    t2 = timeit.timeit('f(n)', 'from __main__ import counting_2 as f, n')
    print('{:10.4f} {:10.4f} | best {} | n {}'.format(
        t1,
        t2,
        '1' if t1 < t2 else '2',
        n))

结果是:

0.0930     0.2469 | best 1 | n 0
0.1616     0.2590 | best 1 | n 1
0.1655     0.2606 | best 1 | n 2
0.2320     0.2682 | best 1 | n 20
0.2929     0.2663 | best 2 | n 21
0.2934     0.2681 | best 2 | n 22
0.3715     0.2696 | best 2 | n 23
0.2331     0.2670 | best 1 | n 24
0.2939     0.2680 | best 2 | n 25
0.2915     0.2663 | best 2 | n 26
0.3766     0.2738 | best 2 | n 27
0.3723     0.2684 | best 2 | n 53
0.2926     0.2692 | best 2 | n 100
0.5247     0.2739 | best 2 | n 500
0.5335     0.2935 | best 2 | n 100000
0.9223     0.3147 | best 2 | n 10000000000
4.4814     0.5307 | best 2 | n 100000000000000000000000000000000000000000000000000

速度差异可能与内置类在 C 中实现并且通常优于纯 python 解决方案这一事实有关。

对于小数字counting_1() 更快,可能是因为在counting_2() 中完成数字转换的开销;但显然对于大量用户来说,这种开销可以忽略不计。

注意:实际持续时间取决于存在的1 的数量,对于我的测试中 20 到 30 之间的数字,这两个函数非常相似,但对于更大的数字,本机 C 实现总是获胜。

【讨论】:

  • 非常感谢您的回答!
猜你喜欢
  • 1970-01-01
  • 2015-05-07
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 2013-03-08
  • 2022-12-15
  • 2022-01-24
相关资源
最近更新 更多