Description
Hello team,
We are working on a project where we are tracing specific performance issues back to the code causing them in the user's code base. We are working on a scenario that behaves in a very different way than what we expected.
For instance, we have the following source code:
public static string StringValidation(string data, char replacementChar, CultureInfo culture)
{
List<string> wordList = DisallowedWords
.Where(word => culture.Equals(CultureInfo.InvariantCulture) || culture.Equals(word.Culture))
.Select(word => word.Text).ToList();
foreach (string word in wordList)
{
data = data.Replace(word, replacementChar.ToString(), ignoreCase: true, culture);
}
return data;
}
.Replace
represents a performance issue, and we are trying to find it in the code base given the following stack trace:
System.ReadOnlySpan`1<wchar>,int32*,value class System.Globalization.CompareOptions,bool)
system.private.corelib.il!System.String.ReplaceCore(value class System.ReadOnlySpan`1<wchar>,value class System.ReadOnlySpan`1<wchar>,value class System.ReadOnlySpan`1<wchar>,class System.Globalization.CompareInfo,value class System.Globalization.CompareOptions)
store!Store.Reviews.ReviewValidation.StringValidation(class System.String,wchar,class System.Globalization.CultureInfo)
store!Store.Reviews.BackgroundReviewValidation+<ExecuteAsync>d__0.MoveNext()
However, the stack trace seems to be "skipping" one frame: the actual .Replace
call. It goes directly to the internal .NET implementation: String.ReplaceCore
. You can see it as well in the following screenshot of the trace in PerfView.
Could you please help us understand what's going on? Is that expected? Shouldn't it also have the .Replace
frame?
We have the corresponding .diagsession
file, in case you find it useful and want us to share it as well.
CC: @xiaomi7732