Recent

Author Topic: How to avoid copying  (Read 1709 times)

BrunoK

  • Hero Member
  • *****
  • Posts: 687
  • Retired programmer
Re: How to avoid copying
« Reply #15 on: February 15, 2025, 04:34:59 pm »
It is not cleaner if Key is a record itself
That would be (untested) :
Code: Pascal  [Select][+][-]
  1. type
  2.   TKey = record
  3.     FTheValue: integer;
  4.   end;
  5.   pKey = ^TKey;
  6.  
  7.   TPair = record
  8.     First: TKey;
  9.     Second: TKey; // Some valid field
  10.   end;
  11.   PPair = ^TPair;
  12.  
  13.   function PairKeyCompare(P1, P2: Pointer): integer;
  14.   var
  15.     pa1: PPair absolute P1;
  16.     pa2: PPair absolute P2;
  17.     pk1, pk2: pKey;
  18.   begin
  19.     pk1 := @pa1^.First;
  20.     pk2 := @pa2^.First;
  21.     if pk1^.FTheValue < pk2^.FTheValue then
  22.       Result := -1
  23.     else if pk1^.FTheValue = pk2^.FTheValue then
  24.       Result := 0
  25.     else
  26.       Result := 1;
  27.   end;
  28.  

d2010

  • Full Member
  • ***
  • Posts: 121
Re: How to avoid copying
« Reply #16 on: February 15, 2025, 04:52:39 pm »
Hi
@d2010: What a load of utter crap and nonsense!!!
I think you're in over your paygrade, sorry mate...
Regards Benny

If you use   inside any DLL+exe then  your source  PairKeyCompare(P1, P2: Pointer) hangup the memory of cpkunzip.dll
Code: [Select]
Library cpkunzip;
Interface
Function PairCompare(p1,p2:pointer):integer;
var
  pa1: PPair absolute P1;
  pa2: PPair absolute P2;
begin
  if pa1^.Key.First < pa2^.Key.First then Result:= -1
  else if pa1^.Key.First = pa2^.Key.First then Result:= 0
  else Result:= 1;
end;

Var boca:word=000;
Procedure ClearSource_str_Files(dir:String);
Begin
...
  boca:=ord(PairCompare(Dir1,Dir2) = 01 )*1 +
           ord(PairCompare(NamF1,Namf2)=01)*64;
...
End;

Function dfn_clear0dir(dirname:string):integer;
Begin udm_free10spincount:=00;
      odutWcMatch:='*';
      odutWcMatch:='*';
      ClearSource_str_Files(dirname);
      result:=RTGOOD;
End;
Export dfn_clear0dir;
Begin
     boca:=00;
End.
{--}
« Last Edit: February 15, 2025, 04:55:33 pm by d2010 »

cdbc

  • Hero Member
  • *****
  • Posts: 1968
    • http://www.cdbc.dk
Re: How to avoid copying
« Reply #17 on: February 15, 2025, 05:01:25 pm »
Hi
@d2010: What the H*LL is this:
Code: Pascal  [Select][+][-]
  1. Library cpkunzip;
  2. Interface
  3. Function PairCompare(p1,p2:pointer):integer;
  4. var
  5.   pa1: PPair absolute P1;
  6.   pa2: PPair absolute P2;
  7. begin
  8.   if pa1^.Key.First < pa2^.Key.First then Result:= -1
  9.   else if pa1^.Key.First = pa2^.Key.First then Result:= 0
  10.   else Result:= 1;
  11. end;
  12.  
  13. Var boca:word;
  14. Function ClearSource_str_Files(dir:String);
  15.  
  16. Begin
  17. ...
  18.   boca:=(PairCompare(Dir1,Dir2) = 01 )*1 +
  19.            (PairCompare(NamF1,Namf2)=01)*2;
  20. ...
  21. End;
  22.  
  23. Function dfn_clear0dir(dirname:string):integer;
  24. Begin udm_free10spincount:=00;
  25.       odutWcMatch:='*';
  26.       odutWcMatch:='*';
  27.       ClearSource_str_Files(dirname);
  28.       result:=RTGOOD;
  29. End;
  30. Export dfn_clear0dir;
  31. Begin
  32.      boca:=f00;
  33. End.
  34. {--}
Do you even try to compile these 'Mushroom Dreams' of yours?!?
Oh, I know, it's Saturday and you're smokin' tha weed....
Well, then have fun mate \ö/
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Amir61

  • New Member
  • *
  • Posts: 35
    • http://Amir.Aavani.net
Re: How to avoid copying
« Reply #18 on: February 16, 2025, 06:32:16 am »
@BrunoK

What you are suggesting is equivalent of the pointer approach I described in my starting post, right?

440bx

  • Hero Member
  • *****
  • Posts: 5081
Re: How to avoid copying
« Reply #19 on: February 16, 2025, 07:23:14 am »
Here are a couple of modified/simplified versions of @BrunoK's code:
Code: Pascal  [Select][+][-]
  1. program _PointerAbsolute;
  2.  
  3. type
  4.   TKey = record
  5.     FTheValue : integer;
  6.   end;
  7.   pKey = ^TKey;
  8.  
  9.   TPair = record
  10.     First   : TKey;
  11.     Second  : TKey; // Some valid field
  12.   end;
  13.   PPair = ^TPair;
  14.  
  15. function PairKeyCompare1(P1, P2 : Pointer): integer;
  16. var
  17.   pa1    : PPair absolute P1;
  18.   pa2    : PPair absolute P2;
  19.  
  20.   v1, v2 : integer;
  21.  
  22. begin
  23.   { making a copy of the FTheValue fields                                     }
  24.  
  25.   v1 := pa1^.First.FTheValue;
  26.   v2 := pa2^.First.FTheValue;
  27.  
  28.   if v1 < v2 then exit(-1);
  29.   if v1 = v2 then exit(-0);
  30.  
  31.   result := 1;
  32. end;
  33.  
  34. function PairKeyCompare2(P1, P2 : Pointer): integer;
  35. var
  36.   pa1    : PPair absolute P1;
  37.   pa2    : PPair absolute P2;
  38.  
  39. begin
  40.   { without making a copy                                                     }
  41.  
  42.   if pa1^.First.FTheValue < pa2^.First.FTheValue then exit(-1);
  43.   if pa1^.First.FTheValue = pa2^.First.FTheValue then exit(-0);
  44.  
  45.   result := 1;
  46. end;
  47.  
  48. var
  49.   v1, v2 : TPair;
  50.  
  51. begin
  52.   PairKeyCompare1(@v1, @v2);
  53.   PairKeyCompare2(@v1, @v2);
  54.  
  55.   readln;
  56. end.                        
  57.  
Compiled with O4 (max optimization), it produces:

Code: ASM  [Select][+][-]
  1. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:27  v1 := pa1^.First.FTheValue;
  2. 00000001000015D0 8B09                     mov ecx,[rcx]
  3. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:28  v2 := pa2^.First.FTheValue;
  4. 00000001000015D2 8B12                     mov edx,[rdx]
  5. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:30  if v1 < v2 then exit(-1);
  6. 00000001000015D4 39CA                     cmp edx,ecx
  7. 00000001000015D6 7E08                     jle +$08    # $00000001000015E0 PAIRKEYCOMPARE1+16 PointerAbsolute.lpr:31
  8. 00000001000015D8 B8FFFFFFFF               mov eax,$FFFFFFFF
  9. 00000001000015DD C3                       ret
  10.  
  11. 00000001000015DE 6690                     nop
  12.  
  13. ; note that edx and ecx are not reloaded (they don't need to)
  14.  
  15. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:31  if v1 = v2 then exit(-0);
  16. 00000001000015E0 39CA                     cmp edx,ecx
  17. 00000001000015E2 7504                     jnz +$04    # $00000001000015E8 PAIRKEYCOMPARE1+24 PointerAbsolute.lpr:33
  18. 00000001000015E4 31C0                     xor eax,eax
  19. 00000001000015E6 C3                       ret
  20. 00000001000015E7 90                       nop
  21. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:33  result := 1;
  22. 00000001000015E8 B801000000               mov eax,$00000001
  23. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:34  end;
  24. 00000001000015ED C3                       ret
  25.  
  26. 00000001000015EE 0000                     add [rax],al
  27.  
  28. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:44  if pa1^.First.FTheValue < pa2^.First.FTheValue then exit(-1);
  29. 00000001000015F0 8B01                     mov eax,[rcx]
  30. 00000001000015F2 3B02                     cmp eax,[rdx]
  31. 00000001000015F4 7D06                     jnl +$06    # $00000001000015FC PAIRKEYCOMPARE2+12 PointerAbsolute.lpr:45
  32. 00000001000015F6 B8FFFFFFFF               mov eax,$FFFFFFFF
  33. 00000001000015FB C3                       ret
  34. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:45  if pa1^.First.FTheValue = pa2^.First.FTheValue then exit(-0);
  35.  
  36. ; it should use eax again instead of loading the value in ecx
  37.  
  38. 00000001000015FC 8B09                     mov ecx,[rcx]
  39. 00000001000015FE 3B0A                     cmp ecx,[rdx]
  40. 0000000100001600 7506                     jnz +$06    # $0000000100001608 PAIRKEYCOMPARE2+24 PointerAbsolute.lpr:47
  41. 0000000100001602 31C0                     xor eax,eax
  42. 0000000100001604 C3                       ret
  43. 0000000100001605 0F1F00                   nop dword ptr [rax]
  44. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:47  result := 1;
  45. 0000000100001608 B801000000               mov eax,$00000001
  46. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:48  end;
  47. 000000010000160D C3                       ret
  48. 000000010000160E 0000                     add [rax],al
  49. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:53  begin
  50. 0000000100001610 488D6424D8               lea rsp,[rsp-$28]
  51. 0000000100001615 E8B6320000               call +$000032B6    # $00000001000048D0 FPC_INITIALIZEUNITS
  52. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:54  PairKeyCompare1(@v1, @v2);
  53. 000000010000161A 488D15FF090100           lea rdx,[rip+$000109FF]    # $0000000100012020
  54. 0000000100001621 488D0DE8090100           lea rcx,[rip+$000109E8]    # $0000000100012010
  55. 0000000100001628 E8A3FFFFFF               call -$0000005D    # $00000001000015D0 PAIRKEYCOMPARE1 PointerAbsolute.lpr:27
  56. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:55  PairKeyCompare2(@v1, @v2);
  57. 000000010000162D 488D15EC090100           lea rdx,[rip+$000109EC]    # $0000000100012020
  58. 0000000100001634 488D0DD5090100           lea rcx,[rip+$000109D5]    # $0000000100012010
  59. 000000010000163B E8B0FFFFFF               call -$00000050    # $00000001000015F0 PAIRKEYCOMPARE2 PointerAbsolute.lpr:44
  60. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:57  readln;
  61. 0000000100001640 E88B6C0000               call +$00006C8B    # $00000001000082D0 fpc_get_input
  62. 0000000100001645 4889C1                   mov rcx,rax
  63. 0000000100001648 E873710000               call +$00007173    # $00000001000087C0 FPC_READLN_END
  64. 000000010000164D E8DE310000               call +$000031DE    # $0000000100004830 FPC_IOCHECK
  65. H:\Dev\Tests\00_PointerAbsolute\PointerAbsolute.lpr:58  end.
  66. 0000000100001652 E889360000               call +$00003689    # $0000000100004CE0 FPC_DO_EXIT
  67. 0000000100001657 90                       nop
  68. 0000000100001658 488D642428               lea rsp,[rsp+$28]
  69. 000000010000165D C3                       ret
  70.  
The code generated using a copy is faster (and better) than the code generated without using a copy.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018