Problem
Every Entity.load() call triggers a full re-serialization and write-back of the entity to storage, even though nothing has changed.
Current load path
storage.get → json.loads → Entity.__init__(**data, _loaded=True) → _save() → serialize() → json.dumps → storage.insert
In __init__, after setting all attributes with _do_not_save=True, the flag is reset and _save() is called unconditionally:
self._do_not_save = True
for k, v in kwargs.items():
if not k.startswith("_"):
setattr(self, k, v)
self._do_not_save = False
self._save() # always runs, even when _loaded=True
_save() then unconditionally serializes and writes back:
data = self.serialize()
if not self._do_not_save:
db.save(self._type, self._id, persisted_data) # json.dumps + storage.insert
Impact per load
- 1x
json.loads (read from storage)
- 1x
serialize() (Python dict construction, MRO walk)
- 1x
json.dumps (redundant write-back)
- 1x
storage.insert (redundant StableBTreeMap write on canister)
- 1x audit
json.dumps (if audit enabled)
That is 3 JSON round-trips + 1 storage write for a read-only operation.
Fix
In __init__, skip _save() when loading an existing entity:
if not self._loaded:
self._save()
This eliminates the redundant serialize + write on every load, cutting JSON overhead roughly in half for read-heavy workloads.
Notes
- The entity registry and context tracking still happen — only the redundant DB write is skipped.
- When
_loaded=True, the data in storage is already up-to-date (we just read it), so writing it back is a no-op with wasted cycles.
- On IC canisters, each
storage.insert hits a StableBTreeMap, so the cost is non-trivial.
- Benchmark tests exist in
tests/src/tests/test_benchmark.py to measure before/after impact.
Problem
Every
Entity.load()call triggers a full re-serialization and write-back of the entity to storage, even though nothing has changed.Current load path
In
__init__, after setting all attributes with_do_not_save=True, the flag is reset and_save()is called unconditionally:_save()then unconditionally serializes and writes back:Impact per load
json.loads(read from storage)serialize()(Python dict construction, MRO walk)json.dumps(redundant write-back)storage.insert(redundant StableBTreeMap write on canister)json.dumps(if audit enabled)That is 3 JSON round-trips + 1 storage write for a read-only operation.
Fix
In
__init__, skip_save()when loading an existing entity:This eliminates the redundant serialize + write on every load, cutting JSON overhead roughly in half for read-heavy workloads.
Notes
_loaded=True, the data in storage is already up-to-date (we just read it), so writing it back is a no-op with wasted cycles.storage.inserthits a StableBTreeMap, so the cost is non-trivial.tests/src/tests/test_benchmark.pyto measure before/after impact.