python的解释性特点,深入理解Python特性(13)

栈(后进先出)与列表或数组不同,栈通常不允许随机访问所包含的对象。插入和删除操作通常称为入栈(push)和出栈(pop)。在性能方面,合理的栈实现在插入和删除操作的预期耗时是0(1)。栈在算法中有广泛的应用,比如用于语言解析和运行时的内存管理(“调用栈”)。树或图数据结构上的深度优先搜索(DFS)是简短而美丽算法,其中就用到了栈。Python中有几种栈实现,每个实现的特性略有不同。列表——简单的内置栈Python的列表在内部以动态数组实现,这意味着在添加或删除时,列表偶尔需要调整元素的存储空间大小。列表会预先分配一些后备存储空间,因此并非每个入栈或出栈操作都需要调整大小,所以这些操作的均摊时间复杂度为O(1)。使用列表作为堆栈应注意下面几个重要的性能问题。为了获得O(1)的插入和删除性能,必须使用append()方法将新项添加到列表的末尾,删除时使用pop()方法从末尾删除。为了获得最佳性能,基于Python列表的栈应该向高索引增长并向低索引缩小。从列表前部添加和删除元素很慢,耗时为O(n),因为这种情况必须移动现有的所有元素来为新元素腾出空间。

2_1614803585592.png

2_16148025434780002.png

collections.deque——快速且稳健的栈deque类实现了一个双端队列,支持在0(1)时间(非均摊)从两端添加和移除元素。所以既可以作为队列也可以作为栈。Python的deque对象以双向链表实现,这为插入和删除元素提供了出色且一致的性能,但是随机访问位于栈中间元素的性能很差,耗时为O(n)。

2_16147994602910001.png

2_16148056300870001.pngqueue.LifoQueue——为并行计算提供锁语义

queue.LifoQueue这个位于Python标准库中的栈实现是同步的,提供了锁语义来支持多个并发的生产者和消费者。

除了LifoQueue之外,queue模块还包含其他几个类,都实现了用于并行计算的多生产者用户队列。

在不同情况下,锁语义既可能会带来帮助也可能会导致不必要的开销。后者的情况下,最好使用list或deque作为通用栈。

2_1614806435723.png

2_1614801955541.png最后发生了阻塞...永远停在了这里:

2_1614802405496.png

队列(先进先出)

队列在算法中有广泛的应用,经常用于解决调度和并行编程问题。在树或图数据结构上进行宽度优先搜索(BFS)是一种简短而美丽的算法,其中就用到了队列。

调度算法通常在内部使用优先级队列。这些是特化的队列,其中元素的顺序不是基于插入时间,而是基于优先级。队列根据元素的键计算到每个元素的优先级。

Python中实现了几个队列,每种实现的特征略有不同,下面来看看。

列表——非常慢的队列

不推荐用列表作为队列使用(除非只处理少量元素):

2_1614799226091.png

collections.deque——快速和稳健的队列

deque类实现了一个双端队列,支持在O(1)时间(非均摊)中从任一端添加或删除元素,可用作队列或栈。

Python的deque对象以双向链表实现,这为插入和删除元素提供了出色且一致的性能,但是随机访问位于栈中间元素的性能很差,耗时为O(n)。

2_1614802553777.png

2_16147980555670002.png

queue.Queue——为并行计算提供锁语义

queue.LQueue这个位于Python标准库中的实现是同步的,提供了锁语义来支持多个并发的生产者和消费者。

除了Queue之外,queue模块还包含其他几个类,都实现了用于并行计算的多生产者用户队列。

在不同情况下,锁语义既可能会带来帮助也可能会导致不必要的开销。后者的情况下,最好使用collections.deque作为通用队列:

2_1614805285219.png

当队列为空,发生阻塞。

multiprocessing.Queue——共享作业队列

multiprocessing.Queue作为共享作业队列来实现,允许多个并发worker并行处理队列中的元素。由于Python存在全局解释器锁(GIL),因此无法在单个解释器进程上执行某些并行化过程,使得大家都转向基于进程的并行化。

作为专门用于在进程中分派工作,以此来绕过GIL的限制。这种类型的队列可以跨进程存储和传输任何可pickle的对象:

2_1614801830055.png最后队列为空时也会发生阻塞。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值