Aug 22, 2025
Kyle Getty
Read Time: ~5 minutes
<aside> 📌 At Tilt (Formerly Empower), we seek individuals who challenge personal assumptions, value ownership and trust, and strive for excellence to inspire and empower their team. If this article connected with you, join our team!
</aside>
<aside>
📎 In the era of blazing fast compute and memory, it’s easy for the performance characteristics of System objects to feel like a thing of the past. But scale can defeat all our expectations in the end. With String,
we need to be considerate, because they are immutable! This means operations like ToUpper()
create a new string in memory, and with large datasets, this can lead to performance issues.
</aside>
https://open.spotify.com/episode/03q1kGWXEfWUo8hFQ6AoFE?si=4aca8acb8dd14244
Let’s take a look at some solutions that C# provides us, and how we can hone in on the places these can drain resources.
As with all performance improvements, we should start with the right diagnostic data to scope our approach. At Tilt, we had been dealing with some spiking CPU on API instances, and we had a hunch it was infrastructure related, but since we weren't sure, we also wanted to rule out application involvement. One of the things we did was get a .NET Profiler Trace using Azure App Service Diagnostic Tools.
In the "Diagnose and solve problems blade" on the WebApp we can see a few tools available for deeper analysis of performance.
The profiler trace will create and download a zip with a .diagsession
file that you can open in PerfView or in an IDE such as Visual Studio. This lets us take a look at hot function paths, and here we can see a lot of CPU usage coming from System.Globalization
Here is the LINQ query driving this usage:
query.Where(entity =>
!ListToCheck.Any(s => entity.SomeText.ToUpper().Contains(s.ToUpper()))
&& !AnotherList.Any(s => entity.SomeText.ToUpper().Contains(s.ToUpper()))