两种功能分析的功能

时间:2018-11-01 09:01:30

标签: python

每运行10,000次,我们得到这些:

Simple list lookup: 0.3219145839975681
Binary trick: 0.37199034500008565

使列表查找成为更快的解决方案。但是,运行100,000次,我们得到了以下信息:

Simple list lookup: 3.265285526002117
Binary trick: 0.3752144949976355

然后,二元技巧显然是优越的(正如我所期望的那样)。

为什么我会得到不同的结果?

代码如下:

from math import pow


POWERS = [pow(2, x) for x in range(0, 31)]


def list_lookup(x):
    """Is a power of two, via a simple list lookup."""
    return x in POWERS


def binary_trick(x):
    """Is a power of two, via a simple binary trick from stackoverflow."""
    return x > 0 and (int(x) & (int(x) - 1)) == 0


def test(func):
    """Tests the function "func" with lots of values."""
    data = [(pow(2, x), True) for x in range(0, 31)]
    data += [(pow(3, x), False) for x in range(1, 31)]  # Not one.
    for x, ex in data:
        assert func(x) is ex, "Debug: x={} → ex={}".format(x, ex)


if __name__ == '__main__':
    import timeit
    print("Simple list lookup: {}".format(
        timeit.timeit("test(list_lookup)",
                      number=100000,
                      globals=globals(),
                      setup="from __main__ import test")))
    print("Binary trick: {}".format(
        timeit.timeit("test(binary_trick)",
                      number=10000,
                      globals=globals(),
                      setup="from __main__ import test")))

1 个答案:

答案 0 :(得分:1)

TL:DR

您有错字。您正在执行test(list_lookup) 100,000次和test(binary_trick) 10,000次。


检查一下:

times = 10000

print("Simple list lookup: {}".format(
    timeit.timeit("test(list_lookup)",
                  number=times,
                  globals=globals(),
                  setup="from __main__ import test")))
print("Binary trick: {}".format(
    timeit.timeit("test(binary_trick)",
                  number=times,
                  globals=globals(),
                  setup="from __main__ import test")))

输出

Simple list lookup: 0.523675318
Binary trick: 0.6955866560000001

times更改为100000的输出

Simple list lookup: 5.717076507
Binary trick: 6.923508393999999

list_lookup总是更快。罪魁祸首似乎是binary_trick叫两次int(x)

通过times = 100000return x > 0 and (int(x) & (int(x) - 1)) == 0进行测试

Simple list lookup: 3.343818478
Binary trick: 4.621393652

binary_trick更改为

x = int(x)
return x > 0 and (x & (x - 1)) == 0

使速度加快1秒:

Simple list lookup: 3.269909124
Binary trick: 3.1319104420000006

但是我们可以通过将list_lookup设置为set_lookup来提高速度:

POWERS = {pow(2, x) for x in range(0, 31)}

并再次测试100,000次:

Simple list lookup: 1.443394541
Binary trick: 2.9750550150000006