Skip to content

Commit a2ab701

Browse files
committed
perf: add Cython-accelerated SerDateType timestamp serializer
Restore serializers.pyx/pxd from the PR #748 branch and add SerDateType that serializes datetime/date/numeric values to 8-byte big-endian int64 millisecond timestamps entirely in C, avoiding Python-level struct.pack. Uses the same timedelta arithmetic as the pure-Python DateType.serialize (Item B) but with C-level int64 byte-swapping. Benchmark shows ~1.5x speedup over the already-optimized Python path for datetime serialization (253 ns vs 381 ns per call).
1 parent 40c82e3 commit a2ab701

3 files changed

Lines changed: 514 additions & 0 deletions

File tree

benchmarks/bench_timeseries.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
# Copyright 2026 ScyllaDB, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
115
#!/usr/bin/env python3
216
"""
317
Microbenchmarks for time-series write and read hot paths.
@@ -77,6 +91,30 @@ def bench_datetype():
7791
bench("deserialize (2025)", "DateType.deserialize(packed_now, 4)", setup_deser)
7892
bench("deserialize (2300)", "DateType.deserialize(packed_far, 4)", setup_deser)
7993

94+
# Cython serializer (if available)
95+
try:
96+
from cassandra.serializers import SerDateType # noqa: F401
97+
98+
print("\n=== SerDateType (Cython) ===")
99+
setup_cy = """\
100+
from cassandra.serializers import SerDateType
101+
from cassandra.cqltypes import DateType
102+
import datetime
103+
ser = SerDateType(DateType)
104+
dt_now = datetime.datetime(2025, 4, 5, 12, 0, 0, 123456)
105+
dt_epoch = datetime.datetime(1970, 1, 1, 0, 0, 1, 0)
106+
d_only = datetime.date(2025, 4, 5)
107+
ts_int = 1712318400000
108+
"""
109+
bench("Cython serialize datetime (2025)", "ser.serialize(dt_now, 4)", setup_cy)
110+
bench(
111+
"Cython serialize datetime (epoch)", "ser.serialize(dt_epoch, 4)", setup_cy
112+
)
113+
bench("Cython serialize date object", "ser.serialize(d_only, 4)", setup_cy)
114+
bench("Cython serialize raw int", "ser.serialize(ts_int, 4)", setup_cy)
115+
except ImportError:
116+
print("\n(serializers.pyx not compiled — skipping Cython benchmark)")
117+
80118

81119
# ---------------------------------------------------------------------------
82120
# varint_pack / varint_unpack

cassandra/serializers.pxd

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Copyright 2026 ScyllaDB, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
cdef class Serializer:
17+
# The cqltypes._CassandraType corresponding to this serializer
18+
cdef object cqltype
19+
20+
cpdef bytes serialize(self, object value, int protocol_version)

0 commit comments

Comments
 (0)