The at() method accesses characters with bounds checking. Write s.at(i) instead of s[i]. If out of range, at() throws an exception instead of causing undefined behavior. Use at() when indices come from user input or calculations that might go wrong.
The exception tells you exactly what happened, making bugs easier to find than silent memory corruption. The cost is small overhead for the check. In tight loops with millions of characters, brackets might be faster.
For most code, safety matters more than microseconds.