两个看似相似的dict语句的性能差异?

时间:2017-02-04 11:52:14

标签: python performance

"要避免的一个半问题是确保你这样做:in dict.keys()而不是-Wall。两者在语义上是等价的,但在性能方面,后者要慢得多(O(n)vs O(1))。我已经看到人们会server.c: In function ‘main’: server.c:33:44: warning: suggest parentheses around assignment used as truth value [-Wparentheses] if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) { 认为它更加明确&因此更好。"

我在网上找到了这条建议。任何人都可以解释并证明上述性能差异吗?这两个看似相似的陈述的工作如何如此不同?

编辑:更准确地说,如何在字典中索引比在列表中索引更快?据我所知,哈希表是链表的数组。该数组是键的数组。因此,在哈希表中查找密钥应该类似于在密钥列表中查找密钥。 (?)

1 个答案:

答案 0 :(得分:3)

仅适用于Python 2。

在Python 3中,dict.keys()返回一个包含源dict_keys对象的视图对象dict

$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
>>> d = { 1: 11, 2:22, 3:33 }
>>> k = d.keys()
>>> k
dict_keys([1, 2, 3])
>>> d
{1: 11, 2: 22, 3: 33}
>>> d[4] = 44
>>> k
dict_keys([1, 2, 3, 4])  #!!! k includes the new key that was added to d
>>> 

因此,在Python 3中,key in dict.keys()几乎与key in dict一样有效执行:

  1. dict.keys()在O(1)时间内创建dict_keys对象,然后
  2. 通过dict_keys将查询操作重新路由回dict,并在O(1)时间内执行该操作。
  3. 与Python 3不同,在Python 2中,dict.keys()返回一个必须在O(n)时间内构建的列表对象:

    $ python2
    Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
    >>> d = { 1: 11, 2:22, 3:33 }
    >>> k = d.keys()
    >>> k
    [1, 2, 3]
    >>> d[4] = 44
    >>> k
    [1, 2, 3]
    >>> 
    

    因此,在Python 2中,key in dict.keys()(作为测试,而不是for key in dict.keys()的一部分)将有两个O(n)时间复杂度的来源:

    1. 构建dict.keys()返回的列表需要O(n)时间
    2. 检查查询值是否在返回的列表中需要另外O(n)时间。