C
C#2mo ago
SWEETPONY

✅ How to optimize this code?

Hello, I'd like to optimize my code. The best time I got: 00:00:00.536 with chunks count = 256 536ms actually is not too bad but is it possible to speed up method?
private async Task<IEnumerable<JsonNode?>?> GetDmnTasksAsync(IReadOnlyList<PassengerArrivalChunk> chunks)
{
var tasks = chunks.Select(async chunk =>
{
var serializedChunk = Serializer.Serialize(new { passengerArrivalChunk = chunk });

using var response = await httpClient
.PostAsync(processingSettings.DmnUrl, new StringContent(serializedChunk, Encoding.UTF32, MediaTypeNames.Application.Json));

var responseMessage = await response.Content.ReadAsStringAsync();
var jsonArray = JsonNode.Parse(responseMessage)?["Tasks"]?.AsArray();

return jsonArray?.Select(el => el).Where(x => x != null);
}).ToList();

var results = await Task.WhenAll(tasks);
return results.SelectMany(result => result ?? []);
}
private async Task<IEnumerable<JsonNode?>?> GetDmnTasksAsync(IReadOnlyList<PassengerArrivalChunk> chunks)
{
var tasks = chunks.Select(async chunk =>
{
var serializedChunk = Serializer.Serialize(new { passengerArrivalChunk = chunk });

using var response = await httpClient
.PostAsync(processingSettings.DmnUrl, new StringContent(serializedChunk, Encoding.UTF32, MediaTypeNames.Application.Json));

var responseMessage = await response.Content.ReadAsStringAsync();
var jsonArray = JsonNode.Parse(responseMessage)?["Tasks"]?.AsArray();

return jsonArray?.Select(el => el).Where(x => x != null);
}).ToList();

var results = await Task.WhenAll(tasks);
return results.SelectMany(result => result ?? []);
}
14 Replies
canton7
canton72mo ago
It looks like you're entirely depending on the network there? Sure there's a bit of JSON deserialization, but network slowness is going to dominate
SWEETPONY
SWEETPONYOP2mo ago
yes, ur right but maybe we can speed up json deserialization or replace string with span etc?
canton7
canton72mo ago
I mean, if you're spending 500ms doing 256 network requests (which doesn't seem to bad at all), 1 or 2ms on json stuff is going to make no observable difference And that's quite conservative -- my guess is that the json stuff is taking sub-millisecond
SWEETPONY
SWEETPONYOP2mo ago
hm, okay, by the way it was 2 seconds when I do this: foreach(var chunk in chunks){ // send requests }
felsokning
felsokning2mo ago
You were using an iterater and were dependent on the return from the PostAsync. As @canton7 said, network slowness and API responsiveness will be your issue. So, foreach --> do 1 --> do http call --> get response --> do 2 --> etc.
canton7
canton72mo ago
Yeah, that's the difference between firing off 256 http requests in parallel, vs firing off one, then doing the second once the first had completed
felsokning
felsokning2mo ago
With Task.WhenAll, you're allowing the ThreadPool scheduler to fire the threads when available; foreach, you're controlling when they fire and it's serially, so one after another.
SWEETPONY
SWEETPONYOP2mo ago
hm can we say to ThreadPool to use 256 threads? imagine we have these threads 😄
felsokning
felsokning2mo ago
To give you an example of slowness, I call this API to get the temperature data. How slow the response is - I have no control over that. https://prodapi.metweb.ie/observations/Dublin/today
canton7
canton72mo ago
You're not blocking threads while the requests are in progress That's the magic of async/await
SWEETPONY
SWEETPONYOP2mo ago
ah I forgot about that, thanks
cap5lut
cap5lut2mo ago
another thing would be, that you could use something like
await using (var responseStream = await response.Content.ReadAsStreamAsync())
{
var node = await JsonNode.ParseAsync(responseStream);
var array = node?["Task"]?.AsArray();
return jsonArray?.Select(el => el).Where(x => x is not null); // is that Select() actually needed?
}
await using (var responseStream = await response.Content.ReadAsStreamAsync())
{
var node = await JsonNode.ParseAsync(responseStream);
var array = node?["Task"]?.AsArray();
return jsonArray?.Select(el => el).Where(x => x is not null); // is that Select() actually needed?
}
that way u dont have to first create a string with the whole response but parse the JSON directly. this would reduce the copying of the whole response by one
SWEETPONY
SWEETPONYOP2mo ago
thanks for helping me
Want results from more Discord servers?
Add your server