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 :cry:

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. :lol:)

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.

:oops:

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.

:oops:
The nice thing of getting old is that you soon forget all about this anyway. :wink:

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. :lol:
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. :wink:
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 :shock:

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! :lol:

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()... :lol:

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... :D)

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