Re: [fpc-pascal] How to avoid Copy
Amir via fpc-pascal schrieb am Sa., 30. Dez. 2023, 08:11: > > > On Dec 29, 2023 9:50 PM, Adriaan van Os wrote: > > Amir--- via fpc-pascal wrote: > > Hi all, > > > > I have a List of record, where the record has a WideString field. > > I have some code like the following: > > > > function check(constref v: TMyRecord; data: TListOfMyRecord): Boolean; > > var > > r: TMyRecord; > > > > begin > > Result := False; > > for r in data do > > if r.State = v.State then > > Exit(True); > > end; > > > > I call this method a lot and the CPU profiling shows a lot of cpu time > > spent on "fpc_copy_proc" (which I assume is doing the deep copy on > > records) from "TCustomListEnumerator.GetCurrent". > > I considered other alternatives like using enumerators but they all need > > a to return a record (and hence copying the widestring field). > > I can think of two solutions to get rid of the wasting(!) so much time > > on "fpc_copy_proc": > > 1) Changing the TMyRecord to TMyClass. But then I need to Create and > > Free a "lot" of objects. > > 2) Update TListOfMyRecord to TListOfPointerToMyRecord. This requires a > > "lot" of memory allocation/fragmentation. > > > > Is there a better solution? > > Pass the data parameter by reference. > > This means I need to have a ListOfMyRecord and a ListOfConstRefMyRecord, > right? > No, that's not a thing. You simply need to declare your "data" parameter as "constref" or "const" as well, just like your "v" parameter. Note: prefer the use of "const" instead of "constref" unless you really need a reference, because the compiler will then pick the optimal way to pass the value (e.g. small ones will be passed by register instead of as an address). Regards, Sven > ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] How to avoid Copy
On Fri, 29 Dec 2023, Amir via fpc-pascal wrote: On Dec 29, 2023 9:50 PM, Adriaan van Os wrote: Amir--- via fpc-pascal wrote: > Hi all, > > I have a List of record, where the record has a WideString field. > I have some code like the following: > > function check(constref v: TMyRecord; data: TListOfMyRecord): Boolean; > var > r: TMyRecord; > > begin > Result := False; > for r in data do > if r.State = v.State then > Exit(True); > end; > > I call this method a lot and the CPU profiling shows a lot of cpu time > spent on "fpc_copy_proc" (which I assume is doing the deep copy on > records) from "TCustomListEnumerator.GetCurrent". > I considered other alternatives like using enumerators but they all need > a to return a record (and hence copying the widestring field). > I can think of two solutions to get rid of the wasting(!) so much time > on "fpc_copy_proc": > 1) Changing the TMyRecord to TMyClass. But then I need to Create and > Free a "lot" of objects. > 2) Update TListOfMyRecord to TListOfPointerToMyRecord. This requires a > "lot" of memory allocation/fragmentation. > > Is there a better solution? Pass the data parameter by reference. This means I need to have a ListOfMyRecord and a ListOfConstRefMyRecord, right? It means you use constref data: TListOfMyRecord or var data: TListOfMyRecord And try to avoid "for r in data" because it will create a copy for each element in the list. I don't know how you defined TListOfMyRecord, but if it is a generic TList, better change it to a TArray or Array of TMyRecord, in which case you can use a pointer to the consecutive records in the array. Generics are convenient, but slow. Michael.___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal