From f42b00be72bebff96bd09a97b14f9f886e928c5d Mon Sep 17 00:00:00 2001 From: "codeflash-ai[bot]" <148906541+codeflash-ai[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 19:35:47 +0000 Subject: [PATCH] Optimize serialize_keras_class_and_config The optimization achieves a **55% speedup** by eliminating redundant function calls to `_shared_object_saving_scope()`. **Key optimizations:** 1. **Reduced function calls**: The original code calls `_shared_object_saving_scope()` twice when both conditions are met - once in the compound `if` statement and again when calling `scope.get_config()`. The optimized version calls it at most once by storing the result in a local variable `scope`. 2. **Short-circuit evaluation**: By checking `obj is not None` first, the optimization avoids calling `_shared_object_saving_scope()` entirely when no object is provided (which happens in many test cases), saving expensive `getattr()` operations on the threading.local object. **Performance impact from profiling:** - `_shared_object_saving_scope()` calls dropped from 4,242 to 1,715 (59% reduction) - The expensive compound condition line went from 76.9% of total time to being eliminated - Overall function time reduced from 16.17ms to 10.40ms **Test case benefits:** - **Basic cases without objects** see 200-260% speedup (most common usage pattern) - **Cases with objects but no scope** see modest improvements or slight slowdowns due to the extra `obj is not None` check - **Large-scale tests** with many objects show consistent 130-170% improvements **Real-world impact:** Based on the function reference, `serialize_keras_class_and_config` is called from `serialize_keras_object`, which is likely in the hot path during model serialization. The optimization is particularly effective when serializing models without shared object scopes (the common case), where it eliminates unnecessary threading.local lookups entirely. --- keras/src/legacy/saving/serialization.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/keras/src/legacy/saving/serialization.py b/keras/src/legacy/saving/serialization.py index 8474363895f2..2ce5fb882072 100644 --- a/keras/src/legacy/saving/serialization.py +++ b/keras/src/legacy/saving/serialization.py @@ -241,11 +241,13 @@ def serialize_keras_class_and_config( # already serialized this config. If so, just use that config. This will # store an extra ID field in the config, allowing us to re-create the shared # object relationship at load time. - if _shared_object_saving_scope() is not None and obj is not None: - shared_object_config = _shared_object_saving_scope().get_config(obj) - if shared_object_config is None: - return _shared_object_saving_scope().create_config(base_config, obj) - return shared_object_config + if obj is not None: + scope = _shared_object_saving_scope() + if scope is not None: + shared_object_config = scope.get_config(obj) + if shared_object_config is None: + return scope.create_config(base_config, obj) + return shared_object_config return base_config