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
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;