Developer forum

Forum » Development » Slow performance in AssortmentNavigationProvider

Slow performance in AssortmentNavigationProvider

Anders Ebdrup
Reply

Hi DW,

 

I have downloaded the latest version of DW (v8.6.1.13), but experience very, very bad performance in the assortment navigation provider, with a response time up to 5 minutes.

 

I have located the main time consuming part to this section of the AssortmentNavigationProvider (se below), but after adding the red part (.Distinct()) the performance is now, not good, but okay. It now takes appr. 0,5 seconds instead of 5 minutes.

 

        Private Function GetGroupsTreeFromAssortments(ByVal assortments As IEnumerable(Of String), ByVal includeParentGroups As Boolean) As List(Of String)
            Dim assortmentGroups As New GroupCollection()
            For Each id As String In assortments.Distinct()
                For Each assortmentRelation As AssortmentRelation In assortmentRelation.GetAssortmentRelationsByAssortment(id)
                    If assortmentRelation.Type = eCommerce.Assortments.AssortmentRelation.RelationType.Group Then
                        Dim groupRelation As AssortmentGroupRelation = CType(assortmentRelation, AssortmentGroupRelation)

 

Will you please try to look into this problem?

 

Best regards, Anders

Capture.PNG

Replies

 
Nicolai Høeg Pedersen
Reply

Hi Anders

I've asked DEV to look into this.

BR Nicolai

 
Anders Ebdrup
Reply

Hi Nicolai,

 

After some more optimizations to the function, where we are gone from a processing time on 5 minutes to 60 ms.

Here are the updated function from the assortment navigation provider (we now use a dictionary to store the groups to have a much faster lookup and have high-lighted the most important changes):

 

       Private Function GetGroupsTreeFromAssortments(ByVal assortments As IEnumerable(Of String), ByVal includeParentGroups As Boolean) As List(Of String)
            Dim assortmentGroups As New Dictionary(Of String, Group)()
            For Each id As String In assortments.Distinct()
                For Each assortmentRelation As AssortmentRelation In assortmentRelation.GetAssortmentRelationsByAssortment(id)
                    If assortmentRelation.Type = eCommerce.Assortments.AssortmentRelation.RelationType.Group Then
                        Dim groupRelation As AssortmentGroupRelation = CType(assortmentRelation, AssortmentGroupRelation)
                        If Not assortmentGroups.ContainsKey(groupRelation.GroupID) Then
                            assortmentGroups.Add(groupRelation.GroupID, groupRelation.Group)
                        End If
                    ElseIf assortmentRelation.Type = eCommerce.Assortments.AssortmentRelation.RelationType.Product Then
                        Dim productRelation As AssortmentProductRelation = CType(assortmentRelation, AssortmentProductRelation)
                        Dim productKey As String = NavigationCache.Current.GetProductCacheKey(productRelation.ProductID, productRelation.ProductVariantID)

                        Dim groups As List(Of String) = Nothing
                        If NavigationCache.Current.ProductGroupsCache.TryGetValue(productKey, groups) Then
                            If Not IsNothing(groups) Then
                                For Each group As String In groups
                                    If Not assortmentGroups.ContainsKey(group) Then
                                        Dim ecomGroup As eCommerce.Products.Group = eCommerce.Products.Group.GetGroupByID(group)
                                        If Not IsNothing(ecomGroup) Then
                                            assortmentGroups.Add(group, ecomGroup)
                                        End If
                                    End If
                                Next
                            End If
                        End If
                        'Else
                        '    Dim shopRelation As AssortmentShopRelation = CType(assortmentRelation, AssortmentShopRelation)
                        '    For Each group As Group In shopRelation.Shop.Groups
                        '        If Not assortmentGroups.ContainsById(group.ID) Then
                        '            assortmentGroups.Add(group)
                        '        End If
                        '    Next
                    End If
                Next
            Next
            If includeParentGroups Then
                Dim parentHierarchicalGroups As New Dictionary(Of String, Group)()
                For Each group As Group In assortmentGroups.Values
                    For Each parent As Group In GetParentGroups(group)
                        If Not parentHierarchicalGroups.ContainsKey(parent.ID) Then
                            parentHierarchicalGroups.Add(parent.ID, parent)
                        End If
                    Next
                Next
                For Each group As Group In parentHierarchicalGroups.Values
                    If Not assortmentGroups.ContainsKey(group.ID) Then
                        assortmentGroups.Add(group.ID, group)
                    End If
                Next
            End If
            Return assortmentGroups.Select(Function(group) group.Key).ToList()
        End Function

 

Best regards, Anders

 
Jonas Krarup Dam
Reply

Hi Anders,

Nicolai is on vacation, so I have taken over this task.

I have added an "investigate and improve" item to our bug tracking system - I will include this new version in that item :-)

 

Thanks,

Jonas

 
Anders Ebdrup
Reply

Sounds great! I have added a bit more optimizations to the last part of the code in my former post.

 

At the same time I get some extra ms out of using TryGetValue in the following function from Group.vb:

        Public ReadOnly Property ParentGroups() As GroupCollection
            Get
                'Return _ParentGroups
                Dim parents As New GroupCollection()

                If Not String.IsNullOrEmpty(ID) Then
                    Dim parentRelations As GroupRelationCollection = GroupRelation.GroupRelationsByChildID(ID)
                    For Each parentRelation As GroupRelation In parentRelations
                        Dim parent As New Dynamicweb.eCommerce.Products.Group
                        If AllGroupsByLanguageID(Context.LanguageID).TryGetValue(parentRelation.ParentID, parent) Then
                            parents.Add(parent)
                        End If
                    Next
                End If

                Return parents
            End Get
        End Property

In stead of accessing the dictionary twice and I think you should consider this approach a lot more places in the source code smiley And remove any usages of "ContainsById", at least before the function has been rewritten to use an index.

 

Best regards, Anders

 
Anders Ebdrup
Reply

Hi Jonas,

 

When do you expect the last corrections/optimizations will be available for download?

All changes does not seem to be implemented in 8.1.6.15

 

Best regards, Anders

 
Jonas Krarup Dam
Reply

Hi Anders,

Good thing we have external QA in your offices - you are right, we missed a bit in our implementation.

It'll be fixed today, and be released in the next hotfix.

The people responsible for setting hotfix release dates have gone home for the weekend, but I will get them to update you with a release time on monday.

Regards, Jonas

 
Kristian Kirkholt
Reply

Hi Anders

The problem TFS#17800 "AssortmentNavigationProvider performance"  has now been fixed in version 8.6.1.16

You are able to find this build in the download section:

http://developer.dynamicweb-cms.com/downloads/dynamicweb-8.aspx

Please contact Dynamicweb Support if you need any additional help regarding this.

Kind Regards
Dynamicweb Support
Kristian Kirkholt

 

 

You must be logged in to post in the forum