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!

Join Tilt.

</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. However scale in the end, can defeat all our expectations. With Strings we need to be considerate because they are immutable! This means operations like ToUpper() create a new string in memory. With large datasets this can lead performance issues.

</aside>

https://open.spotify.com/episode/03q1kGWXEfWUo8hFQ6AoFE?si=4aca8acb8dd14244

Let’s chat on solutions C# provides us here, and how we can hone in on the places these can drain resources.

The Issue

As with all performance improvements it starts with the right diagnostic data to scope our approach. We had been dealing with some spiking CPU on API instances we had a hunch it was infrastructure related but also wanted to rule out application involvement. One of the things we did here 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 we can use for deeper analysis of performance.

image.png

The profiler trace will create and download a zip with a .diagsession file you can open in PerfView or IDE like 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

image.png

Here we can see 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()))