Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the 'Function Body' bottlenecking my application?

The application I am developping runs too slowly.

I have run the performance diagnostics of Visual Studio, and found out that one single function was running 66% of the time, the GetHashCode function of the following class.

Public Class Identifier

    Public Property Name As String

    Public Overrides Function GetHashCode() As Integer
        Return Name.ToUpper().GetHashCode()
    End Function

    Public Overrides Function Equals(other As Object) As Boolean
        Dim otherIdentifier = TryCast(other, Identifier)
        If otherIdentifier Is Nothing Then
            Return False
        Else
            Return String.Equals(Name, otherIdentifier.Name, StringComparison.InvariantCultureIgnoreCase)
        End If
    End Function
End Class

What puzzles me even more, is that in the 'Called functions' panel, I read, in terms of Elapsed Inclusive Time:

  • System.String.ToUpper(): 0.61%
  • System.String.GetHashCode(): 0.21%
  • Function Body: 66.67%

Since the function is doing nothing but call the ToUpper and GetHashCode functions, I have a hard time figuring out what I can improve here.

Could you please help me shed some light on this?

like image 221
Maxime Avatar asked Sep 27 '18 08:09

Maxime


1 Answers

I'm not very familiar with VS performance diagnostics. But here is something mentioned about the Function Body.

Function Body also shows you the total amount of time (and the percentage of time) spent in the function body excluding time spent in calling and called functions

But it doesn't really explain why 2/3 of the time is spent in GetHashCode when the calls to ToUpper and GetHashCode are excluded.

However..

"High values in Function Body may indicate a performance bottleneck within the function itself"

That's obvious, ToUpper always has to create a new string for every string it has to compare. If you're doing that millions of times you have high memory pressure and the GC kicks in. Thats why i would use the StringComparer:

Public Overrides Function GetHashCode() As Integer
    Return StringComparer.InvariantCultureIgnoreCase.GetHashCode(Name)
End Function

You can use it also in Equals

Public Overrides Function Equals(other As Object) As Boolean
   Dim otherIdentifier = TryCast(other, Identifier)
   If otherIdentifier Is Nothing Then Return False
   Return StringComparer.InvariantCultureIgnoreCase.Equals(Name, otherIdentifier.Name)
End Function
like image 126
Tim Schmelter Avatar answered Nov 19 '22 02:11

Tim Schmelter