键入s vs键而不是速度

时间:2018-05-03 18:16:42

标签: python performance set processing-efficiency

我有这段代码:

s = set([5,6,7,8])

if key in s:
    return True

if key not in s:
    return False

在我看来,从理论上讲,它不应该在时间上有所不同,但我可能会遗漏一些内幕。

在处理时间或可读性方面,有没有理由更喜欢一个?

也许这是一个例子:

  

“过早优化是万恶之源”?

简答:不,没有区别。是的,可能是过早的优化。

好的,我跑了这个测试:

import random
s = set([5,6,7,8])
for _ in range(5000000):
    s.add(random.randint(-100000,100000000))

def test_in():
    count = 0
    for _ in range(50000):
        if random.randint(-100000,100000000) in s:
            count += 1
    print(count)

def test_not_in():
    count = 0
    for _ in range(50000):
        if random.randint(-100000,100000000) not in s:
            count += 1
    print(count)

当我计算输出时:

%timeit test_in()
10 loops, best of 3: 83.4 ms per loop

%timeit test_not_in()
10 loops, best of 3: 78.7 ms per loop

但是,这个微小的差异似乎是计算组件的一个症状。平均有47500“不是ins”,但只有2500“ins”。如果我改变两个测试通过,例如:

def test_in():
    for _ in range(50000):
        if random.randint(-100000,100000000) in s:
            pass

结果几乎相同

%timeit test_in()
10 loops, best of 3: 77.4 ms per loop

%timeit test_not_in()
10 loops, best of 3: 78.7 ms per loop

在这种情况下,我的直觉使我失望。我原以为说it is not in the set可能会增加一些额外的处理时间。当我进一步考虑hashmap的作用时,很明显这不是这种情况。

2 个答案:

答案 0 :(得分:3)

你不应该看到差异。集合中的查找时间是不变的。您对该条目进行哈希处理,然后在哈希映射中查找它。所有密钥都在同一时间进行检查,并且在vs中不应该具有可比性。

答案 1 :(得分:0)

timeit的ipython会话中运行简单的性能测试,确认了g.d.d.c的语句。

def one(k, s):
    if k in s:
        return True     

def two(k, s):
    if k not in s:
        return False     

s = set(range(1, 100))

%timeit -r7 -n 10000000 one(50, s)
## 83.7 ns ± 0.874 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit -r7 -n 10000000 two(50, s)
## 86.1 ns ± 1.11 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

这样的优化不会给你带来太多好处,正如评论中指出的那样,实际上会降低你推出错误修正/改进的速度/ ......由于可读性差。对于此类低级别性能提升,我建议您调查CythonNumba