【问题标题】:Are sets really faster than lists? [duplicate]集合真的比列表快吗? [复制]
【发布时间】:2019-04-30 22:28:53
【问题描述】:

有人告诉我,在成员资格测试方面,Python 集合比列表更快。

尽管如此,timeit 表明对于大量值,列表实际上更快。

对于具有更多重复次数的较小数据集,差异会更小,甚至相反,但仍然对数据集没有显着优势(我猜性能问题对于非常大的数据集更重要,不是吗?)

如何解释这些数据?

>>> import timeit
>>> # Few repetitions on a bigger set:
>>> timeit.timeit('10000 in set(range(10000000))', number=10)
9.265543753999737
>>> timeit.timeit('10000 in list(range(10000000))', number=10)
4.788996731000225
>>> # More repetitions on a smaller set:
>>> timeit.timeit('10000 in set(range(10000))', number=100000)
32.068307194000226
>>> timeit.timeit('10000 in list(range(10000))', number=100000)
32.45919990500079

【问题讨论】:

  • sets 更快你已经建立它们 - 把它排除在你的时间
  • 你包括了创建时间,set(range(10000000))list(range(10000000)),这是主导时间的,你需要隔离成员测试,看看什么是真正更好的
  • 如果你只做一个成员资格测试,建立一个set可能不是前进的方向,但如果你做很多测试,你想先建立一个set
  • @Chris_Rands 在这种情况下很好,range 的成员资格测试无论如何都是最快的!
  • @juanpa.arrivillaga 这个人为的例子是(在 Python 3 中)

标签: python performance


【解决方案1】:

你被告知是正确的,在集合中搜索是 O(1),因为成员是使用哈希表存储的。在(未排序的)数组中搜索是 O(n)。

您的测试的问题在于您既要创建集合/数组又要在同一行中搜索它。在这种情况下,您既要测试插入所有项目的速度,又要搜索单个条目。

试试这样的:

test_range = range(10000000)
test_set = set(test_range)
test_array = list(test_range)

timeit.timeit('10000 in test_set', number=10)
timeit.timeit('10000 in test_array', number=10)

【讨论】:

  • 对于 Python lists 的搜索仍然是 O(N),无论是否排序。 in 运算符的实现不会在二分搜索/线性搜索之间进行选择,它总是进行线性搜索
  • 谢谢!我尝试了一个稍微不同的代码(因为timeit 不接受超出其参数范围的任何内容),结果当然非常有利于该集合。我只是不喜欢把事情当作理所当然。现在要阅读有关哈希表的内容:)
猜你喜欢
  • 2016-01-20
  • 2011-10-12
  • 2012-09-15
  • 2018-09-28
  • 2011-09-28
  • 2012-11-03
  • 2012-02-14
  • 1970-01-01
相关资源
最近更新 更多