A model sits behind an endpoint on one GPU. Live requests arrive one at a time, and a batch of one is the least efficient case there is: every run of the model pays a fixed overhead however many items it carries, and a single item leaves most of the hardware idle.
So the server batches. It holds requests briefly and runs them together, which makes each user wait a little longer and lets the same GPU serve far more of them. This problem is about exactly how much longer each user waits.
The server follows these rules:
arrivals lists the time, in milliseconds, at which each request arrives. It is sorted from earliest to latest (ties allowed) and holds at least one request.fixed_ms + per_item_ms * n milliseconds. Requests that arrive while a batch is running wait in the queue.max_batch requests are waiting, ormax_wait milliseconds.max_batch of them. Anyone else stays in the queue for a later batch. A request arriving at the very instant a batch launches is in time to join it, if there is room.Task: write batched_latencies(arrivals, max_batch, max_wait, fixed_ms, per_item_ms), returning the latency of every request, in arrival order, each as a float rounded to 4 decimal places. max_batch is a whole number of at least 1, and the other settings are non-negative numbers.
Worked through, batched_latencies([0, 1, 3, 9], 2, 4, 5, 1):
[8.0, 7.0, 11.0, 11.0].With
max_batchset to1there is no batching at all: every request runs alone and pays the whole fixed overhead for itself, so a burst of traffic piles up behind one request at a time. A batching server pays that overhead once per batch and clears the same burst far sooner. The price is some extra waiting when traffic is light, and that is the trade this function lets you measure.