Search code examples
optimizationtreeviewnested-loopsgmap.net

Optimize nested for loop


I'm using GMAP.Net library for a mapping windows application. I have about 17000 polygons on my Sql Server database. In form load event I select All polygons from database and fill a datatabale then draw polygons one by one from datatable. I also have a treeview which I add all 17000 polygon names to that treeview. Now when I check select all checkbox on treeview I call a function in Treeview node_AfterCheck event like this:

Private Sub node_AfterCheck(sender As Object, e As TreeViewEventArgs)     Handles TreeView1.AfterCheck

   If e.Action <> TreeViewAction.Unknown Then
      Task.Factory.StartNew(Sub()
                                  GetPolygons(e.Node)
                              End Sub, TaskCreationOptions.LongRunning)
   End If
End Sub



Private Sub GetPolygons(node As TreeNode)
            Dim objectId As String
            Dim _polygon As GMapPolygon
            For Each node1 As TreeNode In node.Nodes
                objectId = node1.Name

                For Each _polygon In polyOverlay.Polygons.AsParallel
                    itemTag = _polygon.Tag.ToString.Split("|")
                    If itemTag (0) = node1.Name Then
                        _polygon.IsVisible = node.Checked
                        Exit For
                    End If
                Next
            Next
End sub

this code takes about 40 seconds to run completely. Is there any way to optimize this code to complete in shorter time?


Solution

  • The one thing that I can see that is expensive codewise is the call of Split on the tags of the polygon. But this would be subject to measure.

    To circumvent the Split you could e.g. try to use:

    If _polygon.Tag.StartsWith(node1.Name) Then
    

    Consider this question to find out if IsPrefix is even faster in your case.

    I'm assuming, however, the main trouble is the constant refresh/redraw of the map ("auto refresh") while setting each polygon's visibility. One thing I found in the sources is to set Invalidation on hold:

    // docs: stops immediate markers/route/polygon invalidations; call Refresh to perform single refresh and reset incalidation state
    gmap2.HoldInvalidation = true;
    
    // do your update loop within here
    
    // docs: call this to stop HoldInvalidation and perform single forced instant refresh
    gmap2.Refresh();
    

    Don't have the the opportunity to give it a try right now, but I guess you can go ahead and try and see if that makes a difference.