Skip to content

Commit 94eee43

Browse files
committed
(improvement) query: pre-allocate BoundStatement.values list to avoid repeated .append() growth
1 parent 8c03c2f commit 94eee43

1 file changed

Lines changed: 25 additions & 16 deletions

File tree

cassandra/query.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -673,15 +673,17 @@ def bind(self, values):
673673
(value_len, len(self.prepared_statement.routing_key_indexes)))
674674

675675
self.raw_values = values
676-
self.values = []
676+
# Pre-allocate to avoid repeated list growth reallocations
677+
self.values = [None] * col_meta_len
678+
idx = 0
677679
if ce_policy:
678680
# Column encryption path: check each column for CE policy
679681
for value, col_spec in zip(values, col_meta):
680682
if value is None:
681-
self.values.append(None)
683+
self.values[idx] = None
682684
elif value is UNSET_VALUE:
683685
if proto_version >= 4:
684-
self._append_unset_value()
686+
idx = self._append_unset_value(idx)
685687
else:
686688
raise ValueError("Attempt to bind UNSET_VALUE while using unsuitable protocol version (%d < 4)" % proto_version)
687689
else:
@@ -694,60 +696,67 @@ def bind(self, values):
694696
col_bytes = ce_policy.encrypt(col_desc, col_bytes)
695697
else:
696698
col_bytes = col_spec.type.serialize(value, proto_version)
697-
self.values.append(col_bytes)
699+
self.values[idx] = col_bytes
698700
# OverflowError: Cython int32/float casts may raise on out-of-range values
699701
except (TypeError, struct.error, OverflowError) as exc:
700702
_raise_bind_serialize_error(col_spec, value, exc)
703+
idx += 1
701704
else:
702705
# Fast path: no column encryption, use Cython serializers if available
703706
serializers = self.prepared_statement._serializers
704707
if serializers is not None:
705708
for ser, value, col_spec in zip(serializers, values, col_meta):
706709
if value is None:
707-
self.values.append(None)
710+
self.values[idx] = None
708711
elif value is UNSET_VALUE:
709712
if proto_version >= 4:
710-
self._append_unset_value()
713+
idx = self._append_unset_value(idx)
711714
else:
712715
raise ValueError("Attempt to bind UNSET_VALUE while using unsuitable protocol version (%d < 4)" % proto_version)
713716
else:
714717
try:
715718
col_bytes = ser.serialize(value, proto_version)
716-
self.values.append(col_bytes)
719+
self.values[idx] = col_bytes
717720
# OverflowError: Cython int32/float casts may raise on out-of-range values
718721
except (TypeError, struct.error, OverflowError) as exc:
719722
_raise_bind_serialize_error(col_spec, value, exc)
723+
idx += 1
720724
else:
721725
for value, col_spec in zip(values, col_meta):
722726
if value is None:
723-
self.values.append(None)
727+
self.values[idx] = None
724728
elif value is UNSET_VALUE:
725729
if proto_version >= 4:
726-
self._append_unset_value()
730+
idx = self._append_unset_value(idx)
727731
else:
728732
raise ValueError("Attempt to bind UNSET_VALUE while using unsuitable protocol version (%d < 4)" % proto_version)
729733
else:
730734
try:
731735
col_bytes = col_spec.type.serialize(value, proto_version)
732-
self.values.append(col_bytes)
736+
self.values[idx] = col_bytes
733737
# OverflowError: Cython int32/float casts may raise on out-of-range values
734738
except (TypeError, struct.error, OverflowError) as exc:
735739
_raise_bind_serialize_error(col_spec, value, exc)
740+
idx += 1
741+
742+
# Trim trailing unused slots if fewer values were bound than columns
743+
if idx < col_meta_len:
744+
self.values = self.values[:idx]
736745

737746
if proto_version >= 4:
738747
diff = col_meta_len - len(self.values)
739748
if diff:
740749
for _ in range(diff):
741-
self._append_unset_value()
750+
idx = self._append_unset_value(idx)
742751

743752
return self
744753

745-
def _append_unset_value(self):
746-
next_index = len(self.values)
747-
if self.prepared_statement.is_routing_key_index(next_index):
748-
col_meta = self.prepared_statement.column_metadata[next_index]
754+
def _append_unset_value(self, idx):
755+
if self.prepared_statement.is_routing_key_index(idx):
756+
col_meta = self.prepared_statement.column_metadata[idx]
749757
raise ValueError("Cannot bind UNSET_VALUE as a part of the routing key '%s'" % col_meta.name)
750-
self.values.append(UNSET_VALUE)
758+
self.values[idx] = UNSET_VALUE
759+
return idx + 1
751760

752761
@property
753762
def routing_key(self):

0 commit comments

Comments
 (0)