Open alexander-lubinets opened 8 months ago
@alexander-lubinets Thanks for reporting this issue!
Where you able to do any profiling to identify what the delta is between the first time the request is sent and the second? I'm particularly surprised that using the source generator didn't show any benefit. It might indicate that the issue is coming from a different component.
Hi @alexander-lubinets. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.
See our Issue Management Policies for more information.
@captainsafia Thanks for reply! I've taken multiple snapshots using dotTrace, but I'm not really sure what exactly am I looking for. At first I thought that it's all about jit compilation, but I'm not so sure anymore as System Code and String subsystems are taking their time as well. Perhaps you are more experienced in reading snapshots, so I attached all of them. If I'm taking them in a wrong way maybe you could replicate the issue using repo I mentioned in my original post. I removed response serialization, swagger and debug logs in my repo to make sure they are not making things overcomplicated. I also tried performing request to another endpoint before profiling to make sure that some initial jit compilation is not taken into account as I don't really care about it. Btw, model binding still takes ~50ms if I send request to another endpoint first before taking time measurements. I also tried src gen again and profiled it. It always takes a few more milliseconds to process the request with src gen, which seems strange. I added another branch to my repo 'src-gen' to show how do I enable it, maybe I'm doing it the wrong way: https://github.com/alexander-lubinets/DeserializationLatencyInvestigation/tree/src-gen original snapshots.zip src gen snapshots.zip
I'm trying to deal with 'cold start' issues in my Web API .NET 6 project. There is one particular issue I have difficulties with. Request's Json body deserialization and model binding are painfully slow each time some model is received for the first time after app launch. Issue occurs with any DTO model and it's especially noticeable with (reasonably) large models. It may take up to 100-150ms to perform deserialization and model binding, which is too much. When some DTO model is received for the second time, it takes 1-2ms, which is great. Surely I understand that some compilation takes place during first request and some cache is used during subsequent ones, but still users are complaining and I really want to somehow reduce time spent on model binding during first requests. I tried using source generator as I believed that this is exactly the feature created to deal with this issue, but it didn't provide any difference (I checked in debug that generated classes are actually being used, so I don't believe I messed up with src gen configuration). I also tried .NET 8, issue is still there.
I created a tiny repro project: https://github.com/alexander-lubinets/DeserializationLatencyInvestigation Timestamps of debug logs for the first request are the following:
Same logs for the second request:
The difference is enormous. Out of curiosity I tried performing deserialization manually in code on application startup and received the following results while processing first request:
Obviously better, but far from perfect. Anyway, my real project has hundreds of endpoints and DTOs, so calling their deserialization on app startup is not an option. So, what are your thoughts? Is there anything that can be done with this issue?