Page 1 of 2
AddElement() behaviour
Posted: Thu Mar 07, 2024 10:26 am
by infratec
Yesterday I came across the behaviour of AddElement().
I use a Logger.pbi file which is runs a thread to write the entries in a file. The log entries are first stored in a list for speed reasons.
In the thread I use FirstElement() to always write the correct entry to the log file.
In the log file the entries were not in correct order
I use AddElement() to add the new entries.
I assumed that AddElement() adds the entry at the end of the list.
THIS IS NOT TRUE.
After reading the help, it became clear that AddElement() is more like InsertElement() it adds an entry behind the current element.
I did not respect this.
My 'fix':
Use LastElement() before using AddElement()
Maybe I change this and use PushListPosition() and PopListPosition() in the logger thread which should be faster.
But this is also tricky, because when FisrtElement() is the only element and I delete it after logging, Pop will crash.
So keep in mind:
AddElement() does not adding the element at the end of the list.
In my case the name AddElement() was misleading.
Re: AddElement() behaviour
Posted: Thu Mar 07, 2024 11:01 am
by STARGÅTE
You joined 2008 to this forum and realized 16 years later that your assumption of the behavior of AddElement was wrong? What did you do for 16 years? (I'm just kidding.

)
What is wrong with the same "Add" in AddElement? Why "add" should mean adding an element to the end of the list?
To add elements to the end of a list many other languages use the name "append".
So AppendElement() could imitate a LastElement() : AddElement()
Re: AddElement() behaviour
Posted: Thu Mar 07, 2024 11:03 am
by tored
Yes, if you have multiple consumers of the same list it is important to understand that the list still only has one pointer to the current element, thus each consumer needs to set correct position before doing anything to the list.
I have my own thread pool implementation that uses a list internally for incoming tasks, pushing to end by using LastElement() + AddElement() and popping from beginning by using FirstElement() + DeleteElement() but only if ListSize() is positive.
Re: AddElement() behaviour
Posted: Thu Mar 07, 2024 11:07 am
by infratec
Yes, in all these years I used AddElement() only to create a fresh list.
And in this case it adds always at the end (as expected).
So, I forgot, that this is not always the case.
Maybe I'm getting old.

Re: AddElement() behaviour
Posted: Thu Mar 07, 2024 11:10 am
by AZJIO
I can assume that the addition occurs to the current element. Since we always add sequentially, this caused the feeling that the element was being added to the end of the list.
Code: Select all
NewList f.i()
For i = 1 To 20
AddElement(f())
f() = i
Next
SelectElement(f(), 10)
AddElement(f())
f() = 333
ForEach f()
Debug f()
Next
Re: AddElement() behaviour
Posted: Thu Mar 07, 2024 11:21 am
by tored
infratec wrote: Thu Mar 07, 2024 11:07 am
Maybe I'm getting old.
The nice thing of getting old is that you soon forget all about this anyway.

Re: AddElement() behaviour
Posted: Thu Mar 07, 2024 12:03 pm
by BarryG
infratec wrote: Thu Mar 07, 2024 11:07 amMaybe I'm getting old.
Welcome to the club!

Re: AddElement() behaviour
Posted: Thu Mar 07, 2024 5:28 pm
by mk-soft
I am old ...
I realised that when I was looking for a solution that I found in the forum, but I realised that I had written it myself.
Is probably normal.
Re: AddElement() behaviour
Posted: Thu Mar 07, 2024 9:30 pm
by ChrisR
infratec wrote: Thu Mar 07, 2024 10:26 am
My 'fix':
Use LastElement() before using AddElement()
On my side, I do it with
If AddElement(List()) : MoveElement(List(), #PB_List_Last)
It would be nice to have the MoveElement() flags available in AddElement(List()[, Location]) with Location = #PB_List_First, #PB_List_Last, #PB_List_Before, #PB_List_After (Default)
Re: AddElement() behaviour
Posted: Thu Mar 07, 2024 11:58 pm
by AZJIO
tored wrote: Thu Mar 07, 2024 11:21 am
The nice thing of getting old is that you soon forget all about this anyway.
The best way is to dynamically change the help file. Those questions that are raised should be added to the help file in the “Notes” section. Then people will ask them less often. We may not know much information, but when we open the help file, we see that the significant things are first on the list.
Yesterday I thought, why not make an example of accessing a list item via Peekl() in the help
Re: AddElement() behaviour
Posted: Fri Mar 08, 2024 3:01 am
by skywalk
Thanks for the post!
I read the forum easier than the manual
Now, have to check my code how this might burn me?
Re: AddElement() behaviour
Posted: Fri Mar 08, 2024 4:29 am
by idle
the list object will have pointers to head, current and tail so maybe use a macro AddElementFirst() AddElementLast()
would clear up any befuddlement.
One good thing about getting old is you can have a beer or wine when ever you want and not feel guilty about it!
Code: Select all
Macro AddElementFirst(ls,val)
FirstElement(ls)
InsertElement(ls)
ls = val
EndMacro
Macro AddElementLast(ls,val)
LastElement(ls)
AddElement(ls)
ls = val
EndMacro
Global NewList foo()
AddElementFirst(foo(),1)
AddElementFirst(foo(),2)
AddElementFirst(foo(),3)
AddElementFirst(foo(),4)
ForEach foo()
Debug foo()
Next
AddElement() behaviour
Posted: Mon Apr 01, 2024 8:38 am
by HanPBF
Just realized the same with AddElement()...
addElement is not clear, insertElement is clear (expect before/after current element which would give a nice option).
appendElement is clear (maybe with option #PB_List_atBegin, which makes it again not clear...

)
Re: AddElement() behaviour
Posted: Mon Apr 01, 2024 10:54 am
by jacdelad
Code: Select all
Macro AppendElement(My list)
LastElement(MyList)
AddElement(MyList)
EndMacro
Re: AddElement() behaviour
Posted: Mon Apr 01, 2024 11:53 am
by AZJIO
If it moves to the beginning of the list and then to the end, then the loss is 30% of the time. From this we conclude that LastElement() is calculated not from the beginning, but from the current element, and therefore does not move the pointer, since the element is already the last one. Therefore, using LastElement() does not add any noticeable time.
Code: Select all
DisableDebugger
NewList MyList()
StartTime = ElapsedMilliseconds()
For i = 0 To 10000000
ResetList(MyList())
LastElement(MyList())
AddElement(MyList())
Next
StartTime = ElapsedMilliseconds() - StartTime
EnableDebugger
Debug StartTime