This is an automated email from the ASF dual-hosted git repository.

Cole-Greer pushed a commit to branch 3.7-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/3.7-dev by this push:
     new 5efeb43d43 Speed up Python GraphBinary deserialization (#3504)
5efeb43d43 is described below

commit 5efeb43d437070c6bdb09e17e099f3833fea2a5a
Author: kirill-stepanishin <[email protected]>
AuthorDate: Tue Jul 14 18:34:26 2026 -0700

    Speed up Python GraphBinary deserialization (#3504)
    
    The GraphBinary reader built a `DataType` enum member from the type byte 
for every object it decoded. That per-object enum construction heavily degrades 
deserialization performance on large result sets.
    
    The reader now builds a `{type code: deserializer}` lookup table once up 
front and dispatches on the raw integer instead, avoiding per-object enum 
construction. Behavior is unchanged: an unknown type code still raises 
`ValueError("... is not a valid DataType")`.
    
    Assisted-by: Claude Code:claude-opus-4-8
---
 .../python/gremlin_python/structure/io/graphbinaryV1.py    | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git 
a/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py 
b/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py
index 39a0c3a678..14c73e48a3 100644
--- 
a/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py
+++ 
b/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py
@@ -118,6 +118,9 @@ class DataType(Enum):
 
 NULL_BYTES = [DataType.null.value, 0x01]
 
+# null type code as a plain int, so the per-read null check skips the aenum 
lookup
+_NULL = DataType.null.value
+
 
 def _make_packer(format_string):
     packer = struct.Struct(format_string)
@@ -187,6 +190,9 @@ class GraphBinaryReader(object):
         self.deserializers = _deserializers.copy()
         if deserializer_map:
             self.deserializers.update(deserializer_map)
+        # Mirror of self.deserializers keyed by int type code instead of 
DataType.
+        # Avoids the per-read DataType(bt) call, whose aenum construction 
negatively affects performance on large results.
+        self._deserializer_by_type_code = {dt.value: des.objectify for dt, des 
in self.deserializers.items()}
 
     def read_object(self, b):
         if isinstance(b, bytearray):
@@ -197,11 +203,15 @@ class GraphBinaryReader(object):
     def to_object(self, buff, data_type=None, nullable=True):
         if data_type is None:
             bt = uint8_unpack(buff.read(1))
-            if bt == DataType.null.value:
+            if bt == _NULL:
                 if nullable:
                     buff.read(1)
                 return None
-            return self.deserializers[DataType(bt)].objectify(buff, self, 
nullable)
+            try:
+                objectify = self._deserializer_by_type_code[bt]
+            except KeyError:
+                raise ValueError("%r is not a valid DataType" % bt) from None
+            return objectify(buff, self, nullable)
         else:
             return self.deserializers[data_type].objectify(buff, self, 
nullable)
 

Reply via email to