CPython的deque被实现为64项的双向链表大小的"块"(阵列).除了链表两端的那些块外,这些块都是满的.在IIUC中,当pop/ popleft删除块中的最后一项时,块被释放; 当append/ appendleft尝试添加新项目并且相关块已满时,将分配它们.
我理解使用链接列表而不是链接项列表所列出的优点:
malloc/ free添加/删除的每个项目执行/的运行时成本但是为什么不是首先使用单个动态大小的圆形数组而不是双链表呢?
AFAICT,圆形阵列将保留所有上述优点,并维持(atortized)成本pop*/ append*at O(1)(通过分配,就像在中list).此外,它还可以提高从当前O(n)到索引的索引查找成本O(1).循环数组也可以更简单地实现,因为它可以重用大部分list实现.
我可以在C++这样的语言中看到支持链表的论证,其中可以O(1)使用指针或迭代器从中间删除项目; 但是,python deque没有API来执行此操作.
这是我的代码:
from memory_profiler import profile
@profile
def mess_with_memory():
huge_list = range(20000000)
del huge_list
print "why this kolaveri di?"
Run Code Online (Sandbox Code Playgroud)
当我从解释器运行时,这就是输出:
3 7.0 MiB 0.0 MiB @profile
4 def mess_with_memory():
5
6 628.5 MiB 621.5 MiB huge_list = range(20000000)
7 476.0 MiB -152.6 MiB del huge_list
8 476.0 MiB 0.0 MiB print "why this kolaveri di"
Run Code Online (Sandbox Code Playgroud)
如果你注意到输出,创建巨大的列表消耗621.5 MB,而删除它只需释放152.6 MB.当我检查文档时,我发现了以下声明:
the statement del x removes the binding of x from the namespace referenced by the local scope
Run Code Online (Sandbox Code Playgroud)
所以我猜,它并没有删除对象本身,而只是取消绑定它.但是,它在解除绑定方面做了什么呢?它释放了如此多的空间(152.6 MB) …
问题在这篇文章的最后.
第一个片段:空局部变量字典.
def outer():
x = 1
def inner():
print "Local variables: %s" % locals()
return inner()
print outer()
Run Code Online (Sandbox Code Playgroud)
输出:局部变量:{}
第二个片段:在inner()函数内打印并创建局部变量条目.
def outer():
x = 1
def inner():
print x
print "Local variables: %s" % locals()
return inner()
print outer()
Run Code Online (Sandbox Code Playgroud)
输出:
1
Local variables: {'x': 1}
Run Code Online (Sandbox Code Playgroud)
第三个片段:来自内部函数内部的del x:
def outer():
x = 1
def inner():
print x
print "Local variables: %s" % locals()
del x
return inner()
print outer()
Run Code Online (Sandbox Code Playgroud)
输出:
>>> outer()
Traceback (most recent call last): …Run Code Online (Sandbox Code Playgroud) 我从python中学到了什么:
None is frequently used to represent the absence of a value
当我放入一个列表并用数字和字符串排序.我得到了以下结果,这意味着它是最小的数字?
相反:
>>> sorted([1, 2, None, 4.5, (-sys.maxint - 1), (sys.maxint - 1), 'abc'], reverse=True)
['abc', 9223372036854775806, 4.5, 2, 1, -9223372036854775808, None]
>>>
Run Code Online (Sandbox Code Playgroud)
正常排序:
>>> sorted([1, 2, None, 4.5, (-sys.maxint - 1), (sys.maxint - 1), 'abc'])
[None, -9223372036854775808, 1, 2, 4.5, 9223372036854775806, 'abc']
>>>
Run Code Online (Sandbox Code Playgroud)
python排序函数如何使用None?
在过去,当我需要在紧密循环中使用类似数组的索引查找时,我通常使用元组,因为它们通常看起来非常高效(接近仅使用n个变量).但是,我决定今天质疑这个假设,并得出一些令人惊讶的结果:
In [102]: l = range(1000)
In [103]: t = tuple(range(1000))
In [107]: timeit(lambda : l[500], number = 10000000)
Out[107]: 2.465047836303711
In [108]: timeit(lambda : t[500], number = 10000000)
Out[108]: 2.8896381855010986
Run Code Online (Sandbox Code Playgroud)
元组查找似乎比列表查找长17%!重复实验给出了类似的结果.拆开每个,我发现它们都是:
In [101]: dis.dis(lambda : l[5])
1 0 LOAD_GLOBAL 0 (l)
3 LOAD_CONST 1 (5)
6 BINARY_SUBSCR
7 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
作为参考,典型的10,000,000个全局变量查找/返回需要2.2秒.另外,我在没有lambdas的情况下运行它,你知道,以防万一(注意数字= 100,000,000而不是10,000,000).
In [126]: timeit('t[500]', 't=range(1000)', number=100000000)
Out[126]: 6.972800970077515
In [127]: timeit('t[500]', 't=tuple(range(1000))', number=100000000)
Out[127]: 9.411366939544678
Run Code Online (Sandbox Code Playgroud)
在这里,元组查找需要35%的时间.这里发生了什么?对于非常紧密的循环,这实际上似乎是一个显着的差异.可能是什么导致了这个?
注意,对于分解为变量(例如x,y = t),元组稍微快一点(在我的几次测试中减少约6%的时间),并且从固定数量的参数构造,元组疯狂得快(约83%的时间减少) ).不要将这些结果作为一般规则; 我刚刚完成了一些对大多数项目毫无意义的小型项目.
In [169]: print(sys.version)
2.7.1 (r271:86882M, Nov 30 2010, …Run Code Online (Sandbox Code Playgroud) 我知道这可能被认为是一个非问题,但我为HPC环境编写软件,所以这3.5倍的速度增加实际上有所不同.
In [1]: %timeit 10 / float(98765)
1000000 loops, best of 3: 313 ns per loop
In [2]: %timeit 10 / (98765 * 1.0)
10000000 loops, best of 3: 80.6 ns per loop
Run Code Online (Sandbox Code Playgroud)
我曾经dis看过代码,我认为它float()会变慢,因为它需要一个函数调用(不幸的是我无法dis.dis(float)看到它实际上在做什么).
我想第二个问题是我float(n)应该何时使用,何时使用n * 1.0?
我正在做一个从udp套接字接收样本的音频播放器,一切正常.但是当我实现一个丢失隐藏算法时,播放器未能以例外速率继续产生静音(每个10ms发送一个多个160字节的列表).
当用pyaudio播放音频时,使用阻塞调用写入来播放一些样本,我注意到它在样本持续时间内平均被阻止.所以我创建了一个新的专用流程来播放样本.
主进程处理音频输出流,并使用multiprocessing.Pipe将结果发送到该进程.我决定使用multiprocessing.Pipe,因为它应该比其他方式更快.
不幸的是,当我在虚拟机上运行该程序时,比特率是我在快速PC上获得的一半,它没有达到目标比特率.
经过一些测试,我得出结论,造成延迟的原因是Pipe的功能send.
我做了一个简单的基准测试脚本(见下文),以了解传输到流程的各种方法之间的差异.该脚本不断发送[b'\x00'*160]5秒,并计算总共发送字节对象的字节数.我测试了以下发送方法:"不发送",多处理.管道,多处理.Queue,multiprocessing.Manager,multiprocessing.Listener/Client,最后是socket.socket:
我的"快速"PC运行窗口7 x64的结果:
test_empty : 1516076640
test_pipe : 58155840
test_queue : 233946880
test_manager : 2853440
test_socket : 55696160
test_named_pipe: 58363040
Run Code Online (Sandbox Code Playgroud)
运行Windows 7 x64的VirtualBox VM guest虚拟机的结果,运行Windows 7 x64的主机:
test_empty : 1462706080
test_pipe : 32444160
test_queue : 204845600
test_manager : 882560
test_socket : 20549280
test_named_pipe: 35387840
Run Code Online (Sandbox Code Playgroud)
from multiprocessing import Process, Pipe, Queue, Manager
from multiprocessing.connection import Client, Listener
import time
FS = "{:<15}:{:>15}"
def test_empty():
s = time.time()
sent = 0
while …Run Code Online (Sandbox Code Playgroud) 由于OrderedDict具有列表(具有有序元素)和字典(使用键而不是索引)的特征,因此使用键切片似乎很自然.
>>> from collections import OrderedDict
>>> cities = OrderedDict((('san francisco', 650), ('new york', 212), ('shanghai', 8621), ('barcelona', 42423)))
>>> test['shanghai':] # I want all the cities from shanghai to the end of the list
TypeError: unhashable type
Run Code Online (Sandbox Code Playgroud)
有趣的是,由于OrderedDictionary.__getslice__没有实施,这不是你看到的错误.我尝试添加自己的__getslice__方法OrderedDict,但我一直遇到这个TypeError问题.似乎Python正在进行某种类型检查以强制切片键只是整数,在它们传递给__getslice__函数之前,是多少unpythonic!
>>> class BetterOrderedDict(OrderedDict):
def __getslice__(self, start=None, end=None, step=1):
return 'potato'
>>> test = BetterOrderedDict((('one', 1), ('two', 2), ('three', 3), ('four', 4)))
>>> print test[1:4]
'potato' # ok this makes sense so …Run Code Online (Sandbox Code Playgroud) python dictionary ordereddictionary python-2.7 python-internals
我有一个列表my_list(该列表包含utf8字符串):
>>> len(my_list)
8777
>>> getsizeof(my_list) # <-- note the size
77848
Run Code Online (Sandbox Code Playgroud)
出于某种原因,排序列表(my_sorted_list = sorted(my_list))使用更多内存:
>>> len(my_sorted_list)
8777
>>> getsizeof(my_sorted_list) # <-- note the size
79104
Run Code Online (Sandbox Code Playgroud)
为什么sorted返回一个列表,在内存中占用的空间比初始未排序列表多?
请考虑以下示例:
i=7
j=8
k=10
def test():
i=1
j=2
k=3
return dict((name,eval(name)) for name in ['i','j','k'])
Run Code Online (Sandbox Code Playgroud)
它返回:
>>> test()
{'i': 7, 'k': 10, 'j': 8}
Run Code Online (Sandbox Code Playgroud)
为什么eval不考虑函数内定义的变量?从文档中,您可以选择传递全局变量和本地字典.这意味着什么?最后,我如何修改这个小案例才能使它工作?
python ×10
python-internals ×10
python-3.x ×3
list ×2
cpython ×1
dictionary ×1
eval ×1
memory ×1
optimization ×1
performance ×1
python-2.7 ×1
sockets ×1
sorting ×1
tuples ×1
windows ×1