Page 1 of 1

Performance improvement, accessing a list within a map

Posted: Sat Jan 20, 2024 12:00 am
by PBJim
Hello to all, I bought a copy of PB a while ago and picked up a lot from this forum already. I’d like to ask if the following is possible please.

My application is multi-threaded and has a global map, within which is a list of ids for that key. Each key to the map, and its associated list of ids, will only be written and read by one thread simultaneously, but they can be accessed later by another thread, hence the ‘global’. It’s like this :

Code: Select all

Structure strdata                                              ; Map structure, contains just a list associated with each map key
  List List.s()
EndStructure

Global NewMap DataMap.strdata()
It is working already, but I’d like to improve performance. I use a mutex, allowing a thread to read and write its list, without affecting others. I also reference the list by specifying the key to its map element every time :

Code: Select all

LockMutex(ListMut.i)

AddElement(DataMap(mapkey.s)\List())                  ; Add new list element
DataMap()\List() = dataitem.s

UnlockMutex(ListMut.i)

This can be slow. Is it possible to address the list inside the map, using its @address, therefore first obtain the map key and the address of the list from that, and then avoid the need to repeatedly keep using the map key? Thanks all.

Re: Performance improvement, accessing a list within a map

Posted: Sat Jan 20, 2024 12:34 am
by Mijikai
Somthing like this?

Code: Select all

EnableExplicit

Structure STR_DATA
  List lst.s()
EndStructure

Global NewMap dm.STR_DATA()
Global *ptr_list.STR_DATA
Global *ptr_str.String

*ptr_list = dm("test");<-

AddElement(*ptr_list\lst())

*ptr_list\lst() = "123"
*ptr_str = @*ptr_list\lst()

Debug *ptr_list\lst()
Debug *ptr_str\s

Re: Performance improvement, accessing a list within a map

Posted: Sat Jan 20, 2024 12:53 am
by PBJim
Mijikai wrote: Sat Jan 20, 2024 12:34 am Somthing like this?
Thanks very much, yes that's what I'd hoped for. The syntax takes me a little bit of understanding, but I've adapted it as follows and it appears to work fine, adding three list elements. I think I have the deletion of a map element correct here, but in practice I'd expect a mutex would be necessary.

Code: Select all

EnableExplicit

Structure STR_DATA
  List lst.s()
EndStructure

Global NewMap dm.STR_DATA()
Global *ptr_list.STR_DATA
Global *ptr_str.String

*ptr_list = dm("test");<-

AddElement(*ptr_list\lst())
*ptr_list\lst() = "123"

AddElement(*ptr_list\lst())
*ptr_list\lst() = "456"

AddElement(*ptr_list\lst())
*ptr_list\lst() = "789"


*ptr_str = @*ptr_list\lst()

Debug *ptr_list\lst()
Debug *ptr_str\s


ForEach *ptr_list\lst()
  Debug "--> " + *ptr_list\lst()
Next

; * Deletion would take place in another thread (not the thread that created the list), but I've added it
; * in this case to check it works.
DeleteMapElement(dm(), "test")
I didn't quite understand the line that reads *ptr_str = @*ptr_list\lst() and its comparison with *ptr_list\lst()