Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python是';输入dict';与'不同/更快;输入dict.keys()';_Python_Performance_Dictionary - Fatal编程技术网

Python是';输入dict';与'不同/更快;输入dict.keys()';

Python是';输入dict';与'不同/更快;输入dict.keys()';,python,performance,dictionary,Python,Performance,Dictionary,直觉上,我认为键入dict比键入dict.keys()快,因为键入dict.keys()创建了一个键列表。这个问题是为了确认这是否属实 只是想知道key in dict是否在内部创建/使用一个列表来查找该键是否存在 另外,一种方法比另一种快吗?简短回答: 在python 2中:您的假设是正确的:dict.keys() 在python 3中:您的假设是不正确的:dict.keys()中的与dict中的类似 py2和py3的详细信息如下 Python 2.7回答: 您的假设是正确的,原因如下:

直觉上,我认为
键入dict
键入dict.keys()
快,因为
键入dict.keys()
创建了一个键列表。这个问题是为了确认这是否属实

只是想知道
key in dict
是否在内部创建/使用一个列表来查找该键是否存在


另外,一种方法比另一种快吗?

简短回答:

  • 在python 2中:您的假设是正确的:
    dict.keys()
  • 在python 3中:您的假设是不正确的:dict.keys()中的
    与dict中的
    类似
py2和py3的详细信息如下

Python 2.7回答:

您的假设是正确的,原因如下:

  • dict.keys()
    涉及额外的函数调用(堆栈开销)
  • dict.keys()
    返回一个列表,其中包含内存中的所有键(与惰性生成器对象相反)。因此,它需要分配内存
  • 键入dict
    可以在内部使用set对象,这是一种索引查找
    key in dict.keys()
    是列表中的线性搜索
我创建了一个小的benckmark脚本来说明我的观点:

#! /usr/bin/python2.7

import datetime as dt
import random

dict_size = 1000000
num_iterations = 100

d = {i: i for i in xrange(dict_size)}

def f():
    k = random.randint(0,dict_size-1)
    return (k in d)

def g():
    k = random.randint(0,dict_size-1)
    return (k in d.keys())

def test(func):
    t = dt.datetime.utcnow()
    for i in xrange(num_iterations):
        func()
    print "%s --> %1.6f s" % (func, (dt.datetime.utcnow()-t).total_seconds())

test(f)
test(g)
输出(python 2.7.6 Ubuntu 14.04):

-->0.000598 s
-->5.191553 s
我还测试了nr迭代和dict大小交换(dict只有100项,1M迭代)

-->3.614162 s
-->7.007922秒
这里的结果更加接近

因此,性能差异确实会随着dict的大小而增大

Python 3答案:

我为python 3改编了脚本:

  • xrange
    已消失,请改用
    range
    。(不在测试功能的性能关键内环中,因此性能影响有限)
  • 将大括号与
    打印一起使用
  • 将沙邦行更改为
    #/usr/bin/python3
并在同一台机器上使用python 3.4.3进行了测试

  • dict_size=1000000;num_迭代次数=100

    f-->0.000590秒 g-->0.000565秒

  • dict_size=100;num_迭代次数=1000000

    f-->4.525487秒 g-->4.837232秒


因此,在python 3中,性能差异消失了。

key in dict
使用哈希。对这两种方法进行基准测试将提供一个更明确的答案。has answer here@ozgur是的,谢谢,尽管这个问题不是真的重复,但那里的答案确实回答了这个问题。请注意,
dict.keys()
返回Python 3中类似集合的视图对象,而不是列表。而且它们也不会浪费内存。另外,
dict.keys()
涉及属性查找。请注意,在python3中,
dict.keys()
会返回一个视图,因此在python3中,您的第二点仅部分正确。我认为理论上应该仍然存在差异,尽管差异较小,但在python3中,您仍然有一个属性查找和一个函数调用-这些都需要时间。仅供参考,以下是内部(python3)将
if key in.keys()分派到
if key in dict
的函数:
<function f at 0x7ff2e0126d70> --> 0.000598 s
<function g at 0x7ff2e0126de8> --> 5.191553 s
<function f at 0x7f94cb5e6d70> --> 3.614162 s
<function g at 0x7f94cb5e6de8> --> 7.007922 s