I have a pretty big list of objects, which needs to be received fast from the client. Currently it takes about 2-4 seconds. I now try to use streams to send chunks (e.g. 100 objects in each) I know that GRPC can use streams but in ASP.NET core, how can I achieve this? The normal ASP.NET has PushStreamContent
which is not available in Core. Any solutions out there? I can't really find a proper one online.
So what my Controller currently looks like:
[HttpGet]
public async Task<ActionResult<IEnumerable<Price>>> GetPrices()
{
return await _context.Prices.ToListAsync();
}
This list currently contains around 18700 Items but this number will increase by time.
CodePudding user response:
I'm guessing you're using EF Core based on your example.
If you take a look at Efficient Querying - Buffering and streaming, they recommend using AsEnumerable
to stream the data instead of ToList
, which essentially loads all data into memory before (in your case) returning it to the client. The async version is AsAsyncEnumerable
.
So you should be able to simply change your controller action into:
[HttpGet]
public async Task<ActionResult<IEnumerable<Price>>> GetPrices()
{
return await _context.Prices.AsAsyncEnumerable();
}
Note, that streaming rather than buffering/loading into memory does not mean performance improvements in all cases, but with a large dataset there's a good chance you'll see better performance.
is it a code smell / bad practice to send such big JSON data?
Not necessarily. If you actually need to have the entire dataset client-side, then this is probably the most efficient approach. However, if your dataset is large, you should expect that it takes some time to download. If your download speed is 5 MB/s and your Price
data is 10 MB, then you'll never make it faster than 2 seconds without a better connection. Even if you use a stream from your backend.
Another approach (if that fits your needs) is to introduce paging. That way you can retrieve e.g. 50 items at a time instead of everything and then page through it. But whether it makes sense to use paging from your client is up to you.