perf: speedup pickling of document objects (#28823)

* perf: Use latest pickle protocol

* perf: pop flags from cached documents

This is also the right thing to do, things like `doc.flags.for_update`
shouldn't be "cached".
This commit is contained in:
Ankush Menat 2024-12-18 15:48:04 +05:30 committed by GitHub
parent 9d9193800b
commit 7dd15e3613
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 11 additions and 2 deletions

View file

@ -176,6 +176,11 @@ class BaseDocument:
state.pop("meta", None)
state.pop("permitted_fieldnames", None)
state.pop("_parent_doc", None)
state.pop("flags", None)
def __setstate__(self, state):
self.__dict__ = state
self.flags = _dict()
def update(self, d):
"""Update multiple fields of a doctype using a dictionary of key-value pairs.

View file

@ -10,6 +10,10 @@ from redis.commands.search import Search
import frappe
from frappe.utils import cstr
# 5 is faster than default which is 4.
# Python uses old protocol for backward compatibility, we don't support anything <3.10.
DEFAULT_PICKLE_PROTOCOL = 5
class RedisearchWrapper(Search):
def sugadd(self, key, *suggestions, **kwargs):
@ -63,7 +67,7 @@ class RedisWrapper(redis.Redis):
frappe.local.cache[key] = val
with suppress(redis.exceptions.ConnectionError):
self.set(name=key, value=pickle.dumps(val), ex=expires_in_sec)
self.set(name=key, value=pickle.dumps(val, protocol=DEFAULT_PICKLE_PROTOCOL), ex=expires_in_sec)
def get_value(self, key, generator=None, user=None, expires=False, shared=False):
"""Return cache value. If not found and generator function is
@ -184,7 +188,7 @@ class RedisWrapper(redis.Redis):
# set in redis
try:
super().hset(_name, key, pickle.dumps(value), *args, **kwargs)
super().hset(_name, key, pickle.dumps(value, protocol=DEFAULT_PICKLE_PROTOCOL), *args, **kwargs)
except redis.exceptions.ConnectionError:
pass