Delphi高効率カスタムフォーマットのFormatDateTime

3621 ワード

本人は殲10ブロガーのこのブログの構想に基づいて改善を行い、効率的にFormatDateTime('YYYY-MM-DD HH:NN:SS.ZZZ',Now)を実現することを目的としている.
DelphiXE 3 32 Bits環境で1000000回テストし、
Delphiが持参したFormatDateTime=20405 ms
殲10の最適化関数=2683 ms
本論文の最適化関数=1851 ms
DelphiXE 3 64 Bits環境で1000000回テストし、
Delphiが持参したFormatDateTime=18782 ms
殲10の最適化関数=2091 ms
本明細書の最適化関数=1302 ms
 
type

  UInt32 = LongWord;

  UInt32Array = array[0..0] of UInt32;

  PUInt32Array = ^UInt32Array;

  PUInt32 = ^UInt32;

  PUInt64 = ^UInt64;

  UInt64Array = array[0..0] of UInt64;

  PUInt64Array = ^UInt64Array;



const

  strPatternHandred: PWideChar =

    '00010203040506070809101112131415161718192021222324252627282930' +

    '313233343536373839404142434445464748495051525354555657585960' +

    '6162636465666768697071727374757677787980' +

    '81828384858687888990919293949596979899';

  strPattern10: PWideChar = '0'#0'1'#0'2'#0'3'#0'4'#0'5'#0'6'#0'7'#0'8'#0'9'#0;

  strPatternYear: PWideChar =

    '201420152016201720182019202020212022202320242025202620272028202920302031' +

    '2032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056' +

    '2057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081' +

    '2082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106' +

    '2107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921392131';

  strPatternMonth: PWideChar =

    '-00--01--02--03--04--05--06--07--08--09--10--11--12-';

  strPatternHour: PWideChar =

    ' 00: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: ' +

    '16: 17: 18: 19: 20: 21: 22: 23:';

  strPatternSecond: PWideChar =

    ':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.';



procedure sfNowToBuf(const OutBuf: PWideChar; BufSize: Integer);

var

  Year, Month, Day, HH, MM, SS, ZZZ: WORD;

  P: PUInt32;

  I: Integer;

  SystemTime: TSystemTime;

  lvBuf: array[0..23] of Widechar;

begin

  if BufSize <= 0 then Exit;

  P := @lvBuf[0]; // OutBuff;



  GetLocalTime(SystemTime);

  Year := SystemTime.wYear - 2014;

  Month := SystemTime.wMonth;

  Day := SystemTime.wDay;

  HH := SystemTime.wHour;

  MM := SystemTime.wMinute;

  SS := SystemTime.wSecond;

  ZZZ := SystemTime.wMilliseconds;



   //Year

  PUInt64(P)^ := PUInt64Array(strPatternYear)[Year];  Inc(PUInt64(P));

  //Month

  PUInt64(P)^ := PUInt64Array(strPatternMonth)[Month];  Inc(PUInt64(P));

  //Day

  P^ := PUInt32Array(strPatternHandred)[Day];  Inc(P);

  //HH

  PUInt64(P)^ := PUInt64Array(strPatternHour)[HH];  Inc(PUInt64(P));

  //MM

  P^ := PUInt32Array(strPatternHandred)[MM];  Inc(P);

  //SS

  PUInt64(P)^ := PUInt64Array(strPatternSecond)[SS];  Inc(PUInt64(P));

  //ZZZ

  I := (ZZZ div 10);

  P^ := PUInt32Array(strPatternHandred)[I];  Inc(P);

  I := (ZZZ mod 10);

  P^ := PUInt32Array(strPattern10)[I];



  if BufSize > 23 then BufSize := 23;

  Move(lvBuf, OutBuf^, BufSize*Sizeof(WideChar));

end;