Jump to content

dennis12

Members
  • Content Count

    1
  • Joined

  • Last visited

Community Reputation

0 Neutral
  1. Delphi memory manager is very fast and for small block allocation it has some parallelism built in. I measured IntToStr(-1583749570) at 17ns, CopyIntegerToWideBuffer(-1583749570, Buffer) at 13ns and the version in System.SysUtils without string allocation 7ns. All numbers in nano seconds. Example code below: const CTwoDigitLookup : packed array[0..99] of array[0..1] of Char = ('00','01','02','03','04','05','06','07','08','09', '10','11','12','13','14','15','16','17','18','19', '20','21','22','23','24','25','26','27','28','29', '30','31','32','33','34','35','36','37','38','39', '40','41','42','43','44','45','46','47','48','49', '50','51','52','53','54','55','56','57','58','59', '60','61','62','63','64','65','66','67','68','69', '70','71','72','73','74','75','76','77','78','79', '80','81','82','83','84','85','86','87','88','89', '90','91','92','93','94','95','96','97','98','99'); function DivBy100(i: Cardinal): Cardinal; {$IF Defined(WIN32)} asm MOV ECX, 1374389535 // 1/100 * 2^(32+5) MUL ECX MOV EAX, EDX SHR EAX, 5 end; {$ELSEIF Defined(WIN64))} asm MOV EAX, ECX IMUL RAX, RAX, 1374389535 SHR RAX, 37 end; {$ELSE} inline; begin Result := i div 100; end; {$ENDIF} {$R-} {$Q-} {$POINTERMATH ON} function Int32ToWideBuffer(const AValue: Int32; ABuffer: PChar): Integer; var LVal, LRemainder: UInt32; LDigits: Integer; LNegative: Boolean; begin LVal := Abs(AValue); if LVal >= 10000 then if LVal >= 1000000 then if LVal >= 100000000 then LDigits := 9 + Byte(Ord(LVal >= 1000000000)) else LDigits := 7 + Byte(Ord(LVal >= 10000000)) else LDigits := 5 + Byte(Ord(LVal >= 100000)) else if LVal >= 100 then LDigits := 3 + Byte(Ord(LVal >= 1000)) else LDigits := 1 + Byte(Ord(LVal >= 10)); LNegative := AValue < 0; ABuffer^ := '-'; Inc(ABuffer, Ord(LNegative)); Result := LDigits; Inc(Result, Ord(LNegative)); while LDigits > 1 do begin LRemainder := LVal; LVal := DivBy100(LVal); Dec(LRemainder, LVal * 100); Dec(LDigits, 2); PCardinal(@ABuffer[LDigits])^ := Cardinal(CTwoDigitLookup[LRemainder]); end; if LDigits <> 0 then ABuffer^ := Char(LVal or Ord('0')); end;
×