Python容器相关简单性能测试
今天看了《Python工匠》容器一章,对其中一些内容衍生兴趣,简单测试了一下其性能
copy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
from timeit import timeit
# 1.生成器遍历和列表遍历的速度比较
def gen(n=100000):
for i in range(n):
yield i
def lis(n=100000):
return [i for i in range(n)]
def perf_gen():
for i in gen():
pass
def perf_lis():
for i in lis():
pass
t_gen = timeit(setup="from __main__ import perf_gen", stmt="perf_gen()", number=10000)
t_lis = timeit(setup="from __main__ import perf_lis", stmt="perf_lis()", number=10000)
print(t_gen) # 3.005467499999213(n=10000) 28.504840099994908(n=100000)
print(t_lis) # 1.8407773000071757(n=10000) 24.375115999995614(n=100000)
# 结论
# 元素少的时候,遍历列表比生成器要快,我认为是因为生成器要实时生成,但列表已经生成好了
# 元素很多时,两者差距不大
# 总之还是得根据实际情况来使用,二者性能差距并不大
# 2.insert到不同位置的时间区别
def insert_head(n):
li = []
for i in range(n):
li.insert(0, i)
def insert_end(n):
li = []
for i in range(n):
li.insert(li.__len__(), i)
def insert_end2(n):
li = []
for i in range(n):
li.insert(-1, i)
def append(n):
li = []
for i in range(n):
li.append(i)
t_insert_head = timeit(setup="from __main__ import insert_head", stmt="insert_head(10000)", number=1000)
print(t_insert_head)
t_insert_end = timeit(setup="from __main__ import insert_end", stmt="insert_end(10000)", number=1000)
print(t_insert_end)
t_insert_end2 = timeit(setup="from __main__ import insert_end2", stmt="insert_end2(10000)", number=1000)
print(t_insert_end2)
t_append = timeit(setup="from __main__ import append", stmt="append(10000)", number=1000)
print(t_append)
# 8.290992399997776
# 0.5631236000044737
# 0.26824749998922925
# 0.18099470000015572
# insert时,头插和尾插因为底层实现,必定头插慢
# 而append应该有专门优化过的,比同操作的insert还快,不知道是不是len()有消耗的原因
# 下面看下双端队列deque的性能
from collections import deque
def deque_insert_head(n):
li = deque()
for i in range(n):
li.appendleft(i)
def deque_insert_end(n):
li = deque()
for i in range(n):
li.append(i)
t_deque_insert_head = timeit(setup="from __main__ import deque_insert_head", stmt="deque_insert_head(10000)", number=1000)
print(t_deque_insert_head)
t_deque_insert_end = timeit(setup="from __main__ import deque_insert_end", stmt="deque_insert_end(10000)", number=1000)
print(t_deque_insert_end)
# 0.22433799999998882
# 0.22514420002698898
# 相比list.append差一点,但是首位都快,且与list差距不大
# 3.判断成员是否存在,长短列表用集合判断的时间差别,长列表在头尾位置判断的差别
t_long_list_head = timeit(setup="li = list(range(100000))", stmt="0 in li", number=10000)
t_long_list_rear = timeit(setup="li = list(range(100000))", stmt="99999 in li", number=10000)
t_short_list_head = timeit(setup="li = list(range(100))", stmt="0 in li", number=10000)
t_short_list_rear = timeit(setup="li = list(range(100))", stmt="99 in li", number=10000)
print(t_long_list_head)
print(t_long_list_rear)
print(t_short_list_head)
print(t_short_list_rear)
# 0.00011639999866019934
# 3.8965106999967247
# 0.00011199999426025897
# 0.00371659999655094
# t_long_set_head = timeit(setup="li = list(range(100000))", stmt="0 in set(li)", number=10000)
# t_long_set_rear = timeit(setup="li = list(range(100000))", stmt="99999 in set(li)", number=10000)
# t_short_set_head = timeit(setup="li = list(range(100))", stmt="0 in set(li)", number=10000)
# t_short_set_rear = timeit(setup="li = list(range(100))", stmt="99 in set(li)", number=10000)
# print(t_long_set_head)
# print(t_long_set_rear)
# print(t_short_set_head)
# print(t_short_set_rear)
# 22.197511299993494
# 21.99846269999398
# 0.00856279999425169
# 0.008391000010306016
# 由于上面使用集合时每次都重新创建了集合,存在额外损耗,比较不公平。
# 应该提前将列表转换为集合,查询时直接查询使用
t_long_set_head = timeit(setup="li = set(range(100000))", stmt="0 in li", number=10000)
t_long_set_rear = timeit(setup="li = set(range(100000))", stmt="99999 in li", number=10000)
t_short_set_head = timeit(setup="li = set(range(100))", stmt="0 in li", number=10000)
t_short_set_rear = timeit(setup="li = set(range(100))", stmt="99 in li", number=10000)
print(t_long_set_head)
print(t_long_set_rear)
print(t_short_set_head)
print(t_short_set_rear)
# 0.0001294999965466559
# 0.0001736000122036785
# 0.00012630000128410757
# 0.00013259999104775488
# 可以看出集合确实不受容器大小、元素位置灯限制,只与hash相关。
本文作者:faf4r
本文链接:https://www.cnblogs.com/faf4r/p/18377268
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步