Используйте вместо этого маринованные объекты в качестве ключей словаря.
Используя маринованный объект в качестве ключа, мы можем полностью обойти методы MyObject.__hash__
и MyObject.__eq__
и потенциально ускорить процесс распаковки.
После того, как у вас есть неотобранный словарь, вы можете медленно менять выбранные ключи на фактические экземпляры MyObject по мере необходимости.
p1.py
Создайте словарь, в котором ключи имеют тип MyObject затем засолить их в файл. Создайте словарь, где ключи замаринованы байтами MyObject. Сравните время, необходимое для распаковки каждого словаря.
#!/usr/bin/env python3
import pickle
import pickletools
from pprint import pprint
import random
import string
import time
random.seed(19891225)
class MyObject(object):
def __init__(self, value):
self.value = value
def __eq__(self, other):
exit(1)
return self.value == other.value
def __hash__(self):
time.sleep(10)
return hash(tuple(self.value))
def key_value():
value_len = random.randint(0,len(string.ascii_letters))
value = random.sample(string.ascii_letters, value_len)
return (MyObject(value), value_len)
def object_key_dict(size=10):
return dict([key_value() for i in range(0, size)])
def pickle_key_dict(d):
return {pickle.dumps(k):v for k, v in d.items()}
def pickle_unpickle(obj, filename):
with open(filename, "wb") as pout:
pickle.dump(obj, pout)
print(f"Unpickle Start: {time.strftime('%H:%M:%s')}")
with open(filename, "rb") as pin:
newobj = pickle.load(pin)
print(f"Unpickle complete: {time.strftime('%H:%M:%s')}")
print("-"*20)
return newobj
if __name__ == "__main__":
d = object_key_dict(size=10)
print("Use MyObject instances as dictionary keys")
unpickled_d = pickle_unpickle(d, 'doc.p')
print("\nUse pickled ojbects as dicitonary keys")
pd = pickle_key_dict(unpickled_d)
upd = pickle_unpickle(pd, 'docp.p')
Вывод
Use MyObject instances as dictionary keys
Unpickle Start: 09:25:1589808319
Unpickle complete: 09:26:1589808419
--------------------
Use pickled ojbects as dicitonary keys
Unpickle Start: 09:26:1589808419
Unpickle complete: 09:26:1589808419
--------------------