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 = "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 = "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) all_data, target_data = load_dict_data(2000000, 1000) last_time = find_test(all_data, target_data) #dict查找的性能远远大于list #在list中随着list数据的增大 查找时间会增大 #在dict中查找元素不会随着dict的增大而增大 print(last_time)
不可变对象 都是可hash的, str, fronzenset, tuple,自己实现的类 __hash__ dict的内存花销大,但是查询速度快, 自定义的对象 或者python内部的对象都是用dict包装的
查找效率:set>dict>list
单次查询中:看来list 就是O(n)的;而set做了去重,本质应该一颗红黑树(猜测,STL就是红黑树),复杂度O(logn);dict类似对key进行了hash,然后再对hash生成一个红黑树进行查找,其查找复杂其实是O(logn),并不是所谓的O(1)。O(1)只是理想的实现,实际上很多hash的实现是进行了离散化的。dict比set多了一步hash的过程,so 它比set慢,不过差别不大。