sampsyo/beets — pull request #502 by geigerzaehler (2014-01-21 17:54:41+00:00)
Title: Use generators to stream requests to `/item/?embedded`

This allows us to immediately start sending a response. We don't have to collect all items from the database first and then send them in bulk.

## Performance
I performed a benchmark comparing this *streaming* approach and the *bulk* approach from #501. I used curl to make two request to `/item/?embedded`: first without throttling the download speed and then limiting it to 500kb/s.
```bash
time \
curl --header 'X-Requested-With: XMLHttpRequest' \
"localhost:8337/item/?embedded" > /dev/null

time \
trickle -s -d 500k \
curl --header 'X-Requested-With: XMLHttpRequest' \
"localhost:8337/item/?embedded" > /dev/null
```
My system has a database of 6800 tracks which amounts to 9030k JSON data or 1.3kb/item.

**Donwload time and speed**

stream	bulk
no download limit	7.3s @ 1250kb/s	7.4s @ 1230kb/s
500kb/s download limit	27.8s @ 338kb/s	34.4s @ 247kb/s

The first row shows that the download rate on the local machine is virtually infinite and that both approaches are equivalent. It also shows that all the time is being spent on converting the database cursors to JSON at a rate of about 1250kb/s or 1s/1000 songs.
From the second row we see that streaming is faster by about 7s. These are exactly the 7s from the first run. The bulk server first has to convert the data before it starts to serve, where as the streaming server can start sending immediately.

### Conclusion
The streaming approach is faster by 1 second per 1000 songs as long as the download rate is below 1.2Mb/s.

## Implementation
I used ad `json_generator` utility function to yield the JSON string. This is not well tested and quite specific. Is there a Python library that implements this more generally?