Storage reads/writes (SLOAD/SSTORE) dominate gas cost, exactly as in Solidity. Vyper's built-in overflow checks and bounds checks add a small, predictable overhead per operation in exchange for eliminating a whole bug class — a trade most teams consider worthwhile.
@external
def batch_credit(users: DynArray[address, 50], amounts: DynArray[uint256, 50]):
assert len(users) == len(amounts), "length mismatch"
for i in range(50):
if i >= len(users):
break
self.balances[users[i]] += amounts[i]Favour `@view`/`@pure` where truthful, cache repeated `self.x` reads into a local variable within a function, and keep `DynArray` bounds as tight as the real use case requires.