1. dict 和 list 查找性能的比较
from random import randint
def load_list_data(total_nums, target_nums):
"""
从文件中读取数据,以list的方式返回
:param total_nums: 读取的数量
:param target_nums: 需要查询的数据的数量
"""
all_data = []
target_data = []
file_name = "G:/慕课网课程/AdvancePython/fbobject_idnew.txt"
with open(file_name, encoding="utf8", mode="r") as f_open:
for count, line in enumerate(f_open):
if count < total_nums:
all_data.append(line)
else:
break
for x in range(target_nums):
random_index = randint(0, total_nums)
if all_data[random_index] not in target_data:
target_data.append(all_data[random_index])
if len(target_data) == target_nums:
break
return all_data, target_data
def load_dict_data(total_nums, target_nums):
"""
从文件中读取数据,以dict的方式返回
:param total_nums: 读取的数量
:param target_nums: 需要查询的数据的数量
"""
all_data = {}
target_data = []
file_name = "G:/慕课网课程/AdvancePython/fbobject_idnew.txt"
with open(file_name, encoding="utf8", mode="r") as f_open:
for count, line in enumerate(f_open):
if count < total_nums:
all_data[line] = 0
else:
break
all_data_list = list(all_data)
for x in range(target_nums):
random_index = randint(0, total_nums-1)
if all_data_list[random_index] not in target_data:
target_data.append(all_data_list[random_index])
if len(target_data) == target_nums:
break
return all_data, target_data
def find_test(all_data, target_data):
#测试运行时间
test_times = 100
total_times = 0
import time
for i in range(test_times):
find = 0
start_time = time.time()
for data in target_data:
if data in all_data:
find += 1
last_time = time.time() - start_time
total_times += last_time
return total_times/test_times
if __name__ == "__main__":
all_data, target_data = load_list_data(10000, 1000)
# all_data, target_data = load_list_data(100000, 1000)
# all_data, target_data = load_list_data(1000000, 1000)
# all_data, target_data = load_dict_data(10000, 1000)
# all_data, target_data = load_dict_data(100000, 1000)
# all_data, target_data = load_dict_data(1000000, 1000)
last_time = find_test(all_data, target_data)
print(last_time)
由上可以得出结论:
(1)dict的查找性能远远大于list
(2) 在list中,随着list数据亮的增大,查找的时间也会增大; 在 dict中,查找元素的时间不会随着数据量的增大而增大,其时间复杂度为O(1)
2. 为什么 dict的查找性能会远远的大于 list呢?
是因为dict 中的 key 和set 中的元素值都是 可hash的。
以dict为例,原理如下所示:
dict中建立的hash表如下:
图1
hash表的查询:
图2
故:
(1) dict的key 或者 set的值都必须是可hash的
不可变对象,都是可hash的,str,fronzenset, tuple, 自己实现的类(带有__hash__魔法函数)
(2) dict的内存花销大(hash简单的来说即映射,如图1所示,映射之后,不可能是连续的存在内存空间中的,总有一些内存时空的,当发现内存空间中的“空”只有1/3时,便会触发扩容操作,以免引起hash冲突),但是查询速度快。自定义的对象,或者python内部的对象都是dict包装的。
(3)dict的存储顺序和元素的添加顺序有关
(4)添加的数据有可能改变已有的数据顺序(扩容时,需要将原来的dict,复制移动到新的内存空间,此时将“挤出”已有的“空”,所以每个key的偏移可能改变)