Я подумал, что попробую некоторые измерения, используя линейный таймер Quality Suite NexusDB в этой тестовой программе D7:
{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N+,O-,P+,Q-,R-,S-,T-,U-,V+,W+,X+,Y+,Z1}
program semicolontest;
{$APPTYPE CONSOLE}
uses
SysUtils;
function isThisUseful1(this : string): boolean;
var
i: Integer;
begin
result := false;
try
if this = ''
then
i := 0
else
i := 1
except
;
end;
result := (i > 0)
end;
function isThisUseful2(this : string): boolean;
var
i: Integer;
begin
result := false;
try
if this = ''
then
i := 0
else
i := 1
except
end;
result := (i > 0)
end;
var
Input : String[20];
i : Integer;
Res : Boolean;
begin
Input := 'abcdefg';
writeln('Starting');
for i := 1 to 1000000 do begin
Res := isThisUseful1(Input);
Res := isThisUseful2(Input);
end;
writeln('Done');
// readln;
end.
, которая содержит две версии функции isThisUseful
из вопроса, один с, а другой без точки с запятой в блоке except
. Результаты выполнения этого кода (с извинениями за слегка искаженный макет) следующие:
Line Total Time Hit Count Source
1 - {$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N+,O-,P+,Q-,R-,S-,T-,U-,V+,W+,X+,Y+,Z1}
2 - program semicolontest;
3 -
4 - {$APPTYPE CONSOLE}
5 -
6 - uses
7 - SysUtils;
8 -
9 - function isThisUseful1(this : string): boolean;
10 - var
11 - i: Integer;
12 2.807175 1,000,000 begin
13 0.761388 1,000,000 result := false;
14 2.133202 1,000,000 try
15 1.403061 1,000,000 if this = ''
16 - then
17 - i := 0
18 - else
19 0.826841 1,000,000 i := 1
20 - except
21 - ;
22 - end;
23 0.735419 1,000,000 result := (i > 0)
24 - end;
25 -
26 - function isThisUseful2(this : string): boolean;
27 - var
28 - i: Integer;
29 1.260030 1,000,000 begin
30 0.782293 1,000,000 result := false;
31 0.894420 1,000,000 try
32 0.820860 1,000,000 if this = ''
33 - then
34 - i := 0
35 - else
36 0.873424 1,000,000 i := 1
37 - except
38 -
39 - end;
40 0.778922 1,000,000 result := (i > 0)
41 - end;
42 -
43 - var
44 - Input : String[20];
45 - i : Integer;
46 - Res : Boolean;
47 -
48 1.167140 1 begin
49 -
50 0.000036 1 Input := 'abcdefg';
51 -
52 0.641347 1 writeln('Starting');
53 0.000026 1 for i := 1 to 1000000 do begin
54 - Res := isThisUseful1(Input);
55 - Res := isThisUseful2(Input);
56 0.669066 1,000,000 end;
57 0.402661 1 writeln('Done');
58 - // readln;
59 - end.
60 -
Обратите внимание, что для строки 21 не записывается время, точка с запятой в блоке try ...except
для простого причина того, что, как и ожидалось, код для него не генерируется.
Для полноты ниже приведены разборки isThisUseful1
и isThisUseful2
isThisUseful1:
Address Bytes Text Block #
00408620h [semicolontest.dpr.12] begin
00408620h 55 push ebp 1
00408621h 8BEC mov ebp, esp 1
00408623h 83C4F4 add esp, 0FFFFFFF4h ; (-0Ch) 1
00408626h 53 push ebx 1
00408627h 56 push esi 1
00408628h 57 push edi 1
00408629h 8945FC mov [ebp-04h], eax 1
0040862Ch 8B45FC mov eax, [ebp-04h] 1
0040862Fh E87CB7FFFF call System::LStrAddRef ;(00403DB0h) 1
00408634h 33C0 xor eax, eax 1
00408636h 55 push ebp 1
00408637h 689A864000 push offset @@6 1
0040863Ch 64FF30 push fs:[eax] 1
0040863Fh 648920 mov fs:[eax], esp 1
00408642h [semicolontest.dpr.13] result := false;
00408642h C645FB00 mov byte ptr [ebp-05h], 00h 1
00408646h [semicolontest.dpr.14] try
00408646h 33C0 xor eax, eax 1
00408648h 55 push ebp 1
00408649h 6872864000 push offset @@3 1
0040864Eh 64FF30 push fs:[eax] 1
00408651h 648920 mov fs:[eax], esp 1
00408654h [semicolontest.dpr.15] if this = ''
00408654h 837DFC00 cmp dword ptr [ebp-04h], 00h 1
00408658h 7507 jnz @@1 1
0040865Ah [semicolontest.dpr.17] i := 0
0040865Ah 33C0 xor eax, eax 2
0040865Ch 8945F4 mov [ebp-0Ch], eax 2
0040865Fh EB07 jmp @@2 2
00408661h [semicolontest.dpr.19] i := 1
00408661h @@1:
00408661h C745F401000000 mov dword ptr [ebp-0Ch], 01h 3
00408668h @@2:
00408668h 33C0 xor eax, eax 4
0040866Ah 5A pop edx 4
0040866Bh 59 pop ecx 4
0040866Ch 59 pop ecx 4
0040866Dh 648910 mov fs:[eax], edx 4
00408670h EB0A jmp @@4 4
00408672h @@3:
00408672h E9DDACFFFF jmp System::HandleAnyException ;(00403354h) 5
00408677h [semicolontest.dpr.21] ;
00408677h E8B8AEFFFF call System::DoneExcept ;(00403534h) 5
0040867Ch [semicolontest.dpr.23] result := (i > 0)
0040867Ch @@4:
0040867Ch 837DF400 cmp dword ptr [ebp-0Ch], 00h 6
00408680h 0F9F45FB setnle [ebp-05h] 6
00408684h 33C0 xor eax, eax 6
00408686h 5A pop edx 6
00408687h 59 pop ecx 6
00408688h 59 pop ecx 6
00408689h 648910 mov fs:[eax], edx 6
0040868Ch 68A1864000 push offset @@7 6
00408691h @@5:
00408691h 8D45FC lea eax, [ebp-04h] 7
00408694h E8BFB3FFFF call System::LStrClr ;(00403A58h) 7
00408699h C3 ret 7
0040869Ah @@6:
0040869Ah E9E1ADFFFF jmp System::HandleFinally ;(00403480h) 8
0040869Fh EBF0 jmp @@5 8
004086A1h @@7:
004086A1h 8A45FB mov al, [ebp-05h] 9
004086A4h [semicolontest.dpr.24] end;
004086A4h 5F pop edi 9
004086A5h 5E pop esi 9
004086A6h 5B pop ebx 9
004086A7h 8BE5 mov esp, ebp 9
004086A9h 5D pop ebp 9
004086AAh C3 ret 9
isThisUseful2:
Address Bytes Text Block #
00408620h [semicolontest.dpr.12] begin
00408620h 55 push ebp 1
00408621h 8BEC mov ebp, esp 1
00408623h 83C4F4 add esp, 0FFFFFFF4h ; (-0Ch) 1
00408626h 53 push ebx 1
00408627h 56 push esi 1
00408628h 57 push edi 1
00408629h 8945FC mov [ebp-04h], eax 1
0040862Ch 8B45FC mov eax, [ebp-04h] 1
0040862Fh E87CB7FFFF call System::LStrAddRef ;(00403DB0h) 1
00408634h 33C0 xor eax, eax 1
00408636h 55 push ebp 1
00408637h 689A864000 push offset @@6 1
0040863Ch 64FF30 push fs:[eax] 1
0040863Fh 648920 mov fs:[eax], esp 1
00408642h [semicolontest.dpr.13] result := false;
00408642h C645FB00 mov byte ptr [ebp-05h], 00h 1
00408646h [semicolontest.dpr.14] try
00408646h 33C0 xor eax, eax 1
00408648h 55 push ebp 1
00408649h 6872864000 push offset @@3 1
0040864Eh 64FF30 push fs:[eax] 1
00408651h 648920 mov fs:[eax], esp 1
00408654h [semicolontest.dpr.15] if this = ''
00408654h 837DFC00 cmp dword ptr [ebp-04h], 00h 1
00408658h 7507 jnz @@1 1
0040865Ah [semicolontest.dpr.17] i := 0
0040865Ah 33C0 xor eax, eax 2
0040865Ch 8945F4 mov [ebp-0Ch], eax 2
0040865Fh EB07 jmp @@2 2
00408661h [semicolontest.dpr.19] i := 1
00408661h @@1:
00408661h C745F401000000 mov dword ptr [ebp-0Ch], 01h 3
00408668h @@2:
00408668h 33C0 xor eax, eax 4
0040866Ah 5A pop edx 4
0040866Bh 59 pop ecx 4
0040866Ch 59 pop ecx 4
0040866Dh 648910 mov fs:[eax], edx 4
00408670h EB0A jmp @@4 4
00408672h @@3:
00408672h E9DDACFFFF jmp System::HandleAnyException ;(00403354h) 5
00408677h [semicolontest.dpr.21] ;
00408677h E8B8AEFFFF call System::DoneExcept ;(00403534h) 5
0040867Ch [semicolontest.dpr.23] result := (i > 0)
0040867Ch @@4:
0040867Ch 837DF400 cmp dword ptr [ebp-0Ch], 00h 6
00408680h 0F9F45FB setnle [ebp-05h] 6
00408684h 33C0 xor eax, eax 6
00408686h 5A pop edx 6
00408687h 59 pop ecx 6
00408688h 59 pop ecx 6
00408689h 648910 mov fs:[eax], edx 6
0040868Ch 68A1864000 push offset @@7 6
00408691h @@5:
00408691h 8D45FC lea eax, [ebp-04h] 7
00408694h E8BFB3FFFF call System::LStrClr ;(00403A58h) 7
00408699h C3 ret 7
0040869Ah @@6:
0040869Ah E9E1ADFFFF jmp System::HandleFinally ;(00403480h) 8
0040869Fh EBF0 jmp @@5 8
004086A1h @@7:
004086A1h 8A45FB mov al, [ebp-05h] 9
004086A4h [semicolontest.dpr.24] end;
004086A4h 5F pop edi 9
004086A5h 5E pop esi 9
004086A6h 5B pop ebx 9
004086A7h 8BE5 mov esp, ebp 9
004086A9h 5D pop ebp 9
004086AAh C3 ret 9
(я сам пытался сравнить их, пытаясь сравнить их, и не собирался тратить свое время, прогоняя их мимо BeyondCompare).
В любом случае, я думаю, что это показывает, что, как указано мной и другими, компилятор не генерирует код для строки, содержащей только точку с запятой в блоке try...except
, и не должен делать это нигде, хотя, как отмечалось, существуют случаи, когда наличие или в противном случае точка с запятой изменяет семантику кода и, следовательно, сгенерированный код.