Circular buffer for streaming data in Signal Processing - Time & Space Complexity
We want to understand how the time to process streaming data with a circular buffer changes as the data size grows.
How does the buffer handle new data efficiently over time?
Analyze the time complexity of the following circular buffer update code.
buffer = [0] * size
write_pos = 0
def add_sample(sample):
global write_pos
buffer[write_pos] = sample
write_pos = (write_pos + 1) % size
This code adds one new sample to the buffer, overwriting the oldest data when full.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Writing one sample to the buffer array at the current position.
- How many times: Once per new sample added, no loops inside the function.
Each new sample requires a single write operation regardless of buffer size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 writes |
| 100 | 100 writes |
| 1000 | 1000 writes |
Pattern observation: The number of operations grows directly with the number of samples added, not with buffer size.
Time Complexity: O(1)
This means adding each new sample takes the same small amount of time, no matter how big the buffer is.
[X] Wrong: "Adding a sample takes longer as the buffer gets bigger because it has to move all data."
[OK] Correct: The circular buffer overwrites data in place using a position index, so it does not shift or move existing data.
Understanding this helps you explain how to handle continuous data efficiently, a useful skill in real-time signal processing tasks.
"What if we added a loop inside add_sample to process the entire buffer each time? How would the time complexity change?"
Practice
circular buffer in streaming data processing?Solution
Step 1: Understand circular buffer concept
A circular buffer stores data in a fixed-size space and overwrites old data when full.Step 2: Compare options with concept
Only To store a fixed amount of recent data by overwriting old data describes overwriting old data to keep recent data, matching the circular buffer purpose.Final Answer:
To store a fixed amount of recent data by overwriting old data -> Option DQuick Check:
Circular buffer = overwrite old data [OK]
- Thinking circular buffer sorts data
- Assuming it stores all data permanently
- Confusing with data compression
Solution
Step 1: Identify circular buffer initialization
A circular buffer needs a fixed-size list to hold data, initialized with placeholders like None.Step 2: Check each option
buffer = [None] * 5 creates a list of size 5 with None values, suitable for a circular buffer. Others do not create fixed-size buffers.Final Answer:
buffer = [None] * 5 -> Option AQuick Check:
Fixed-size list = [None]*5 [OK]
- Using empty list which is size zero
- Using range which creates fixed values, not placeholders
- Using single element list instead of fixed size
buffer after all writes?buffer = [None] * 3
write_pos = 0
for val in [10, 20, 30, 40]:
buffer[write_pos] = val
write_pos = (write_pos + 1) % 3
print(buffer)Solution
Step 1: Trace buffer writes and positions
Writes happen at positions 0,1,2, then wrap to 0 again. Values written: 10->pos0, 20->pos1, 30->pos2, 40->pos0 (overwrite 10).Step 2: Determine final buffer content
After all writes, buffer = [40, 20, 30] because 40 overwrites 10 at position 0.Final Answer:
[40, 20, 30] -> Option AQuick Check:
Last write overwrites pos0 = 40 [OK]
- Ignoring wrap-around and overwriting
- Assuming buffer grows beyond fixed size
- Miscalculating write_pos modulo
buffer = [None] * 4
write_pos = 0
for val in [5, 6, 7, 8, 9]:
buffer[write_pos] = val
write_pos = write_pos + 1 # Missing modulo operation
print(buffer)Solution
Step 1: Analyze write_pos update logic
write_pos increments but never resets or wraps, so it will go out of buffer index range.Step 2: Identify fix for circular behavior
write_pos must use modulo with buffer size to wrap around and overwrite old data correctly.Final Answer:
write_pos should reset to 0 after reaching buffer size -> Option CQuick Check:
Modulo needed for circular index [OK]
- Forgetting modulo causes index error
- Changing buffer size instead of fixing index
- Thinking initialization is wrong
Solution
Step 1: Understand buffer size and writes
Buffer size is 4, but 6 readings were written, so first 2 readings were overwritten by the last 2.Step 2: Determine overwritten readings and order
First two readings (positions 0 and 1) were overwritten. The buffer shows latest 4 readings: 15,18,20,22. The oldest is at write_pos (2), so order from oldest to newest is [20, 22, 15, 18].Final Answer:
Readings 15 and 18 overwritten; order is [20, 22, 15, 18] -> Option BQuick Check:
Overwrite first 2; order starts at write_pos [OK]
- Confusing which readings are overwritten
- Not understanding order after wrap
- Assuming buffer grows beyond fixed size
Ready to prove it?
Pass the test and this pattern moves unknown
