I just came across an efficiency issue when using management operators that I’d
like to fix before the next release and we have backwards compatibility
problems.
Basically the problem is that the Copy operator doesn’t know if the source
value is actually mapped to memory or just a temporary value so we’re forced to
always copy memory (just to be safe) even when a simple move would be good
enough. C++ has a similar idea of rvalues and lvalues and a copy and move
constructor which addresses this.
Here’s a little example of the problem. What I propose is that we either add a
3rd boolean parameter to the Copy operator or add a new Move operator which is
preferred over the Copy operator if it exists (this is much more work obviously
but maybe has some benefit).
================================
{$mode objfpc}
{$modeswitch advancedrecords}
program test;
type
generic TList<T> = record
data: array of T;
constructor Create(num: integer);
class operator Copy(constref src: TList; var dest: TList);
end;
constructor TList.Create(num: integer);
begin
SetLength(data, num);
end;
class operator TList.Copy(constref src: TList; var dest: TList);
begin
// ...if we knew the “src” was a temporary would could simply swap the data...
dest.data := system.copy(src.data);
end;
var
a: specialize TList<integer>;
begin
// TList.Create allocates a new array but we don’t really need to copy
// on assignment because the source is a temporary object that doesn’t
// actually exist at any static address.
a := specialize TList<integer>.Create(10);
end.
Regards,
Ryan Joseph
_______________________________________________
fpc-devel maillist - [email protected]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel