Optimization of a sorting algorithm
Posted: Thu Sep 28, 2023 5:46 pm
Hello again
,
this post is a spin-off from this conversation, which has moved thematically in a different direction.
I would like to ask here again if anyone has tips if and how to optimize this code to sort a structured list.
As you can see in the illustration, each list entry has an entry number (A) and some entries have a reference entry (B) that is referenced.
The sorting should now work in such a way that a referenced entry always comes before the entry that references it in the list.
(the red arrows are showing the reference path!)

This is my approach to achieve this.
The sorting in my use case is about max. 100 entries, nevertheless I would be interested if this can be optimized further.
I didn't measure efficiency in runtime, but rather in the number of items to process in the two loops. And I think that the list is still processed here far too often.
I also haven't tried yet if a previous sorting using SortStructuredList() reduces the subsequent sorting effort.
Glad to hear any hints and comments.
Kurzer
EDIT: PS: I updated the code and was able to reduce the number of accesses to the list from 42 accesses to 41 accesses with the current version. LOL
this post is a spin-off from this conversation, which has moved thematically in a different direction.
I would like to ask here again if anyone has tips if and how to optimize this code to sort a structured list.
As you can see in the illustration, each list entry has an entry number (A) and some entries have a reference entry (B) that is referenced.
The sorting should now work in such a way that a referenced entry always comes before the entry that references it in the list.
(the red arrows are showing the reference path!)

This is my approach to achieve this.
The sorting in my use case is about max. 100 entries, nevertheless I would be interested if this can be optimized further.
Code: Select all
Structure MyStruct
Entry.i
RefEntry.i
EndStructure
NewList StructList.MyStruct()
AddElement(StructList()) : StructList()\Entry = 100
AddElement(StructList()) : StructList()\Entry = 200 : StructList()\RefEntry =300
AddElement(StructList()) : StructList()\Entry = 300 : StructList()\RefEntry =600
AddElement(StructList()) : StructList()\Entry = 400
AddElement(StructList()) : StructList()\Entry = 500 : StructList()\RefEntry =600
AddElement(StructList()) : StructList()\Entry = 600 : StructList()\RefEntry =800
AddElement(StructList()) : StructList()\Entry = 700
AddElement(StructList()) : StructList()\Entry = 800 : StructList()\RefEntry =700
; SortStructuredList(StructList(), #PB_Sort_Ascending, OffsetOf(MyStruct\RefEntry), TypeOf(MyStruct\RefEntry))
ForEach StructList()
Debug "Entry: " + Str(StructList()\Entry) + " - Ref to: " + Str(StructList()\RefEntry)
Next
Debug "----------------------------"
SearchStart = 0
SearchEnd = ListSize(StructList()) - 1
ProcessCounter = 0
For i = SearchStart To SearchEnd - 1
Debug "Processing entry no. " + Str(i)
SelectElement(StructList(), i)
ProcessCounter + 1
If StructList()\RefEntry > 0
*Entry = @StructList()
RefEntry.i = StructList()\RefEntry
Debug " Searching for RefEntry: " +Str(RefEntry)
For j = i + 1 To SearchEnd
SelectElement(StructList(), j)
ProcessCounter + 1
Debug " Search @pos " + Str(j) + "... entry " + Str(StructList()\Entry)
If StructList()\Entry = RefEntry
If StructList()\RefEntry > 0
Debug " Found! Move entry from position " + Str(j) + " before entry at position " + Str(i) + " and restart the search at the last processed entry."
i - 1
Else
Debug " Found! Move entry from position " + Str(j) + " before entry at position " + Str(i) + " and restart the search at the following entry after the last processed entry."
EndIf
MoveElement(StructList(), #PB_List_Before, *Entry)
Break
EndIf
If j = SearchEnd And SearchStart < SearchEnd
Debug "No need to move, continue the search with the next entry."
EndIf
Next
EndIf
Next
Debug ""
Debug "--------------" + Str(ProcessCounter) + " entries processed ----------------------------"
Debug ""
ForEach StructList()
Debug "Entry: " + Str(StructList()\Entry) + " - Ref to: " + Str(StructList()\RefEntry)
Next
I didn't measure efficiency in runtime, but rather in the number of items to process in the two loops. And I think that the list is still processed here far too often.
I also haven't tried yet if a previous sorting using SortStructuredList() reduces the subsequent sorting effort.
Glad to hear any hints and comments.
Kurzer
EDIT: PS: I updated the code and was able to reduce the number of accesses to the list from 42 accesses to 41 accesses with the current version. LOL
Debug output wrote: [19:04:21] [Debug] Entry: 100 - Ref to: 0
[19:04:21] [Debug] Entry: 200 - Ref to: 300
[19:04:21] [Debug] Entry: 300 - Ref to: 600
[19:04:21] [Debug] Entry: 400 - Ref to: 0
[19:04:21] [Debug] Entry: 500 - Ref to: 600
[19:04:21] [Debug] Entry: 600 - Ref to: 800
[19:04:21] [Debug] Entry: 700 - Ref to: 0
[19:04:21] [Debug] Entry: 800 - Ref to: 700
[19:04:21] [Debug] ----------------------------
[19:04:21] [Debug] Processing entry no. 0
[19:04:21] [Debug] Processing entry no. 1
[19:04:21] [Debug] Searching for RefEntry: 300
[19:04:21] [Debug] Search @pos 2... entry 300
[19:04:21] [Debug] Found! Move entry from position 2 before entry at position 1 and restart the search at the last processed entry.
[19:04:21] [Debug] Processing entry no. 1
[19:04:21] [Debug] Searching for RefEntry: 600
[19:04:21] [Debug] Search @pos 2... entry 200
[19:04:21] [Debug] Search @pos 3... entry 400
[19:04:21] [Debug] Search @pos 4... entry 500
[19:04:21] [Debug] Search @pos 5... entry 600
[19:04:21] [Debug] Found! Move entry from position 5 before entry at position 1 and restart the search at the last processed entry.
[19:04:21] [Debug] Processing entry no. 1
[19:04:21] [Debug] Searching for RefEntry: 800
[19:04:21] [Debug] Search @pos 2... entry 300
[19:04:21] [Debug] Search @pos 3... entry 200
[19:04:21] [Debug] Search @pos 4... entry 400
[19:04:21] [Debug] Search @pos 5... entry 500
[19:04:21] [Debug] Search @pos 6... entry 700
[19:04:21] [Debug] Search @pos 7... entry 800
[19:04:21] [Debug] Found! Move entry from position 7 before entry at position 1 and restart the search at the last processed entry.
[19:04:21] [Debug] Processing entry no. 1
[19:04:21] [Debug] Searching for RefEntry: 700
[19:04:21] [Debug] Search @pos 2... entry 600
[19:04:21] [Debug] Search @pos 3... entry 300
[19:04:21] [Debug] Search @pos 4... entry 200
[19:04:21] [Debug] Search @pos 5... entry 400
[19:04:21] [Debug] Search @pos 6... entry 500
[19:04:21] [Debug] Search @pos 7... entry 700
[19:04:21] [Debug] Found! Move entry from position 7 before entry at position 1 and restart the search at the following entry after the last processed entry.
[19:04:21] [Debug] Processing entry no. 2
[19:04:21] [Debug] Searching for RefEntry: 700
[19:04:21] [Debug] Search @pos 3... entry 600
[19:04:21] [Debug] Search @pos 4... entry 300
[19:04:21] [Debug] Search @pos 5... entry 200
[19:04:21] [Debug] Search @pos 6... entry 400
[19:04:21] [Debug] Search @pos 7... entry 500
[19:04:21] [Debug] No need to move, continue the search with the next entry.
[19:04:21] [Debug] Processing entry no. 3
[19:04:21] [Debug] Searching for RefEntry: 800
[19:04:21] [Debug] Search @pos 4... entry 300
[19:04:21] [Debug] Search @pos 5... entry 200
[19:04:21] [Debug] Search @pos 6... entry 400
[19:04:21] [Debug] Search @pos 7... entry 500
[19:04:21] [Debug] No need to move, continue the search with the next entry.
[19:04:21] [Debug] Processing entry no. 4
[19:04:21] [Debug] Searching for RefEntry: 600
[19:04:21] [Debug] Search @pos 5... entry 200
[19:04:21] [Debug] Search @pos 6... entry 400
[19:04:21] [Debug] Search @pos 7... entry 500
[19:04:21] [Debug] No need to move, continue the search with the next entry.
[19:04:21] [Debug] Processing entry no. 5
[19:04:21] [Debug] Searching for RefEntry: 300
[19:04:21] [Debug] Search @pos 6... entry 400
[19:04:21] [Debug] Search @pos 7... entry 500
[19:04:21] [Debug] No need to move, continue the search with the next entry.
[19:04:21] [Debug] Processing entry no. 6
[19:04:21] [Debug]
[19:04:21] [Debug] --------------41 entries processed ----------------------------
[19:04:21] [Debug]
[19:04:21] [Debug] Entry: 100 - Ref to: 0
[19:04:21] [Debug] Entry: 700 - Ref to: 0
[19:04:21] [Debug] Entry: 800 - Ref to: 700
[19:04:21] [Debug] Entry: 600 - Ref to: 800
[19:04:21] [Debug] Entry: 300 - Ref to: 600
[19:04:21] [Debug] Entry: 200 - Ref to: 300
[19:04:21] [Debug] Entry: 400 - Ref to: 0
[19:04:21] [Debug] Entry: 500 - Ref to: 600
