标签: python-internals

提高Python中非常大的字典的性能

我发现如果我在开头初始化一个空字典,然后在for循环中添加元素到字典中(大约110,000个键,每个键的值是一个列表,也在循环中增加),速度下降为for循环去.

我怀疑问题是,字典在初始化时并不知道密钥的数量而且它没有做一些非常聪明的事情,所以也许存储冲突变得非常频繁而且速度变慢.

如果我知道密钥的数量以及这些密钥究竟是什么,那么在python中是否有任何方法可以使dict(或哈希表)更有效地工作?我依稀记得,如果你知道密钥,你可以巧妙地设计哈希函数(完美哈希?)并预先分配空间.

python performance dictionary hashtable python-internals

52
推荐指数
1
解决办法
2万
查看次数

为什么variable1 + = variable2比variable1 = variable1 + variable2快得多?

我继承了一些Python代码,用于创建巨大的表(最多19列宽5000行).在屏幕上绘制表格需要9秒钟.我注意到使用以下代码添加了每一行:

sTable = sTable + '\n' + GetRow()
Run Code Online (Sandbox Code Playgroud)

哪里sTable是一个字符串.

我把它改为:

sTable += '\n' + GetRow()
Run Code Online (Sandbox Code Playgroud)

我注意到桌子现在出现了六秒钟.

然后我改为:

sTable += '\n%s' % GetRow()
Run Code Online (Sandbox Code Playgroud)

基于这些Python性能提示(仍然是六秒).

由于这被称为大约5000次,它突出了性能问题.但为什么会有这么大的差异呢?为什么编译器没有在第一个版本中发现问题并对其进行优化?

html python string performance python-internals

52
推荐指数
1
解决办法
1796
查看次数

len()关于集合和列表的复杂性

len()关于集合和列表的复杂性同样是O(1).为什么需要更多时间来处理集合?

~$ python -m timeit "a=[1,2,3,4,5,6,7,8,9,10];len(a)"
10000000 loops, best of 3: 0.168 usec per loop
~$ python -m timeit "a={1,2,3,4,5,6,7,8,9,10};len(a)"
1000000 loops, best of 3: 0.375 usec per loop
Run Code Online (Sandbox Code Playgroud)

它是否与特定基准相关,因为它需要更多时间来构建集而不是列表,基准也考虑到了这一点?

如果创建set对象比创建列表需要更多时间,那么潜在的原因是什么?

python time-complexity python-3.x python-internals

51
推荐指数
4
解决办法
3773
查看次数

为什么大小为2⁶³36字节,但2⁶³-1只有24字节?

Python中的所有东西都是一个对象.因此Python中int的大小将比平常大.

>>> sys.getsizeof(int())
24
Run Code Online (Sandbox Code Playgroud)

好的,但为什么还需要12个字节才能进行2?³比较2?³ - 1,而不仅仅是一个?

>>> sys.getsizeof(2**63)
36
>>> sys.getsizeof(2**62)
24
Run Code Online (Sandbox Code Playgroud)

我得到的2?³是一个long和2?³-1一个int,但为什么12个字节的区别?

不再直观,我尝试了一些其他的东西:

>>> a = 2**63
>>> a -= 2**62
>>> sys.getsizeof(a)
36
Run Code Online (Sandbox Code Playgroud)

a即使它现在可以在int中,仍然存储为long.所以这并不奇怪.但:

>>> a -= (2**63 - 1)
>>> a = 2**63
>>> a -= (2**63 - 1)
>>> a
1L
>>> sys.getsizeof(a)
28
Run Code Online (Sandbox Code Playgroud)

一个新的尺寸.

>>> a = 2**63
>>> a -= 2**63
>>> a
0L
>>> sys.getsizeof(a)
24
Run Code Online (Sandbox Code Playgroud)

回到24个字节,但仍然很长.

我得到的最后一件事:

>>> sys.getsizeof(long())
24
Run Code Online (Sandbox Code Playgroud)

题:

内存存储在这些场景中如何工作? …

python cpython python-2.7 python-internals

51
推荐指数
2
解决办法
5309
查看次数

Python Bytecode究竟是如何在CPython中运行的?

我试图了解Python的工作原理(因为我一直都在使用它!).根据我的理解,当你运行python script.py之类的东西时,脚本转换为字节码,然后解释器/ VM/CPython - 实际上只是一个C程序 - 读取python字节码并相应地执行程序.

这个字节码是如何读入的?它是否类似于在C中读取文本文件的方式?我不确定Python代码是如何转换为机器代码的.是这样的情况,Python解释器(CLI中的python命令)实际上只是一个已经转换为机器代码的预编译C程序,然后python字节码文件只是通过该程序?换句话说,我的Python程序是否从未实际转换为机器代码?python解释器是否已经在机器代码中,所以我的脚本永远不必是?

python cpython python-internals

50
推荐指数
3
解决办法
9977
查看次数

为什么从列表中创建列表会使其更大?

我在使用sys.getsizeof相同的列表时看到了一些不一致的地方.(Python 2.7.5)

>>> lst = [0,1,2,3,4,5,6,7,8,9]
>>> sys.getsizeof(lst)
76
>>> lst2 = list(lst)
>>> sys.getsizeof(lst2)
104
>>> lst3 = list(lst2)
>>> sys.getsizeof(lst3)
104
>>> sys.getsizeof(lst[:])
76
>>> sys.getsizeof(lst2[:])
76
Run Code Online (Sandbox Code Playgroud)

有人有简单的解释吗?

python list python-internals

50
推荐指数
2
解决办法
1570
查看次数

如何在Python中解析对变量的引用

这个消息有点长,有很多例子,但我希望它能帮助我和其他人更好地掌握Python 2.7中变量和属性查找的全部故事.

我正在使用PEP 227(http://www.python.org/dev/peps/pep-0227/)的条款来代码块(例如模块,类定义,函数定义等)和变量绑定(例如作为赋值,参数声明,类和函数声明,for循环等)

我使用的术语变量,可以在不点叫名字,并需要与对象名称限定(如obj.x的属性x对象obj的)名称属性.

Python中有三个范围用于所有代码块,但功能如下:

  • 本地
  • 全球
  • 内建

Python中只有四个块用于函数(根据PEP 227):

  • 本地
  • 封闭功能
  • 全球
  • 内建

变量绑定到块并在块中找到它的规则非常简单:

  • 任何变量绑定到块中的对象都会使此变量本地为此块,除非该变量被声明为全局变量(在这种情况下变量属于全局范围)
  • 使用规则LGB(本地,全局,内置)为所有块查找对变量的引用,但是函数
  • 使用规则LEGB(本地,封闭,全局,内置)仅为函数查找对变量的引用.

让我知道验证这条规则的例子,并展示许多特殊情况.对于每个例子,我都会给出我的理解.如果我错了,请纠正我.对于最后一个例子,我不明白结果.

例1:

x = "x in module"
class A():
    print "A: "  + x                    #x in module
    x = "x in class A"
    print locals()
    class B():
        print "B: " + x                 #x in module
        x = "x in class B"
        print locals()
        def f(self):
            print "f: " + x             #x in module
            self.x = "self.x in f"
            print …
Run Code Online (Sandbox Code Playgroud)

python variables scope python-2.7 python-internals

49
推荐指数
3
解决办法
4904
查看次数

为什么硬编码这个列表比计算它慢?

我想将此序列的前1024个术语分配给列表.我最初猜测硬编码这个列表将是最快的方法.我还尝试在算法上生成列表,发现这比硬编码更快.因此,我测试了各种折衷方法,使用越来越长的硬编码列表,并在算法上扩展到1024项.我找到的最快的方法是对前128个项目进行硬编码并生成其余的项目.

我想了解为什么对序列中的前128项进行硬编码并计算剩余部分比对所有1024项进行硬编码要快.代码和配置文件结果如下所示,使用Python 3.4.2 Shell(IDLE)和cProfile timeit( 感谢Veedrac对改进的性能分析代码的回答).我已将硬编码列表留在一条非常长的行上,以避免使用数字行混乱问题,但除此之外,代码不需要水平滚动.

def hardcoded():
    m = [0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,9,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,10]

def softcoded():
    m = [0]
    for k in range(10):
        m += m
        m[-1] += 1

def hybrid():
    m = [0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7]
    for k in range(3):
        m += m
        m[-1] += 1

from timeit import Timer

def p_time(func, n=10000):
    print(func.__name__)
    print(min(Timer(func).repeat(10, n)) / n)

p_time(hardcoded)
p_time(softcoded)
p_time(hybrid)
Run Code Online (Sandbox Code Playgroud)

计时

hardcoded
1.593102711162828e-05
softcoded
1.1183638458442147e-05
hybrid
9.69246251002005e-06
Run Code Online (Sandbox Code Playgroud)

我跑了几次所有的时间并粘贴在最低点.

python performance python-3.x python-internals

48
推荐指数
2
解决办法
4801
查看次数

无序Python集的"顺序"

我知道Python中的集合是无序的,但我对它们显示的"顺序"感到好奇,因为它似乎是一致的.它们似乎每次都以相同的方式乱序:

>>> set_1 = set([5, 2, 7, 2, 1, 88])
>>> set_2 = set([5, 2, 7, 2, 1, 88])
>>> set_1
set([88, 1, 2, 5, 7])
>>> set_2
set([88, 1, 2, 5, 7])
Run Code Online (Sandbox Code Playgroud)

......和另一个例子:

>>> set_3 = set('abracadabra')
>>> set_4 = set('abracadabra')
>>> set_3
set(['a', 'r', 'b', 'c', 'd'])
>>>> set_4
set(['a', 'r', 'b', 'c', 'd'])
Run Code Online (Sandbox Code Playgroud)

我只是好奇为什么会这样.有帮助吗?

python python-internals

47
推荐指数
2
解决办法
9436
查看次数

运算符'非常奇怪'的行为方法

为什么是第一个结果False,如果不是True

>>> from collections import OrderedDict
>>> OrderedDict.__repr__ is OrderedDict.__repr__
False
>>> dict.__repr__ is dict.__repr__
True
Run Code Online (Sandbox Code Playgroud)

python methods python-2.7 python-internals

47
推荐指数
1
解决办法
2317
查看次数