2012-05-16 17 views
17

Una condizione comune che tutti i programmi dovrebbero fare è verificare se la stringa è vuota o meno.Qual è il modo migliore per controllare una stringa vuota in Delphi?

Prendere prospetti indicati

(1)

if Length(Str)=0 then 
    // do something 

(2)

if Str='' then 
    // do something 
+2

Nessun grosso problema, se me lo chiedi. Fanno esattamente la stessa cosa, e nessuno è più veloce dell'altro. –

+8

Il secondo sembra produrre meno codice (una istruzione CMP). –

+2

@SertacAkyuz: Realmente, immagino che avrebbero prodotto lo stesso codice. Tuttavia, non penso seriamente che le prestazioni siano un problema qui. –

risposta

35

In XE2, if str = '' compila a meglio codice più veloce per stringhe Ansi e Unicode. if Length(str) = 0 compila a codice migliore per stringhe Wide.

programma di test:

{$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 Project172; 

{$APPTYPE CONSOLE} 

{$R *.res} 

var 
    sa1,sa2: AnsiString; 
    sw1,sw2: WideString; 
    su1,su2: UnicodeString; 

begin 
    if Length(sa1) = 0 then 
    ; 
    if sa2 = '' then 
    ; 
    if Length(sw1) = 0 then 
    ; 
    if sw2 = '' then 
    ; 
    if Length(su1) = 0 then 
    ; 
    if su2 = '' then 
    ; 
end. 

codice compilato:

Project172.dpr.14: if Length(sa1) = 0 then 
004050E2 A19C9B4000  mov eax,[$00409b9c] 
004050E7 85C0    test eax,eax 
004050E9 7405    jz $004050f0 
004050EB 83E804   sub eax,$04 
004050EE 8B00    mov eax,[eax] 
004050F0 85C0    test eax,eax 

Project172.dpr.16: if sa2 = '' then 
004050F2 833DA09B400000 cmp dword ptr [$00409ba0],$00 

Project172.dpr.18: if Length(sw1) = 0 then 
004050F9 A1A49B4000  mov eax,[$00409ba4] 
004050FE 85C0    test eax,eax 
00405100 7407    jz $00405109 
00405102 83E804   sub eax,$04 
00405105 8B00    mov eax,[eax] 
00405107 D1E8    shr eax,1 
00405109 85C0    test eax,eax 

Project172.dpr.20: if sw2 = '' then 
0040510B A1A89B4000  mov eax,[$00409ba8] 
00405110 33D2    xor edx,edx 
00405112 E839E8FFFF  call @WStrEqual 

Project172.dpr.22: if Length(su1) = 0 then 
00405117 A1AC9B4000  mov eax,[$00409bac] 
0040511C 85C0    test eax,eax 
0040511E 7405    jz $00405125 
00405120 83E804   sub eax,$04 
00405123 8B00    mov eax,[eax] 
00405125 85C0    test eax,eax 

Project172.dpr.24: if su2 = '' then 
00405127 833DB09B400000 cmp dword ptr [$00409bb0],$00 

La differenza è ancora più grande se l'ottimizzazione è disabilitato.

Project172.dpr.14: if Length(sa1) = 0 then 
004050E2 A19C9B4000  mov eax,[$00409b9c] 
004050E7 8945EC   mov [ebp-$14],eax 
004050EA 837DEC00   cmp dword ptr [ebp-$14],$00 
004050EE 740B    jz $004050fb 
004050F0 8B45EC   mov eax,[ebp-$14] 
004050F3 83E804   sub eax,$04 
004050F6 8B00    mov eax,[eax] 
004050F8 8945EC   mov [ebp-$14],eax 
004050FB 837DEC00   cmp dword ptr [ebp-$14],$00 

Project172.dpr.16: if sa2 = '' then 
004050FF 833DA09B400000 cmp dword ptr [$00409ba0],$00 

Project172.dpr.18: if Length(sw1) = 0 then 
00405106 A1A49B4000  mov eax,[$00409ba4] 
0040510B 8945E8   mov [ebp-$18],eax 
0040510E 837DE800   cmp dword ptr [ebp-$18],$00 
00405112 740D    jz $00405121 
00405114 8B45E8   mov eax,[ebp-$18] 
00405117 83E804   sub eax,$04 
0040511A 8B00    mov eax,[eax] 
0040511C D1E8    shr eax,1 
0040511E 8945E8   mov [ebp-$18],eax 
00405121 837DE800   cmp dword ptr [ebp-$18],$00 

Project172.dpr.20: if sw2 = '' then 
00405125 A1A89B4000  mov eax,[$00409ba8] 
0040512A 33D2    xor edx,edx 
0040512C E81FE8FFFF  call @WStrEqual 

Project172.dpr.22: if Length(su1) = 0 then 
00405131 A1AC9B4000  mov eax,[$00409bac] 
00405136 8945E4   mov [ebp-$1c],eax 
00405139 837DE400   cmp dword ptr [ebp-$1c],$00 
0040513D 740B    jz $0040514a 
0040513F 8B45E4   mov eax,[ebp-$1c] 
00405142 83E804   sub eax,$04 
00405145 8B00    mov eax,[eax] 
00405147 8945E4   mov [ebp-$1c],eax 
0040514A 837DE400   cmp dword ptr [ebp-$1c],$00 

Project172.dpr.24: if su2 = '' then 
0040514E 833DB09B400000 cmp dword ptr [$00409bb0],$00 
+1

Con "migliore" intendi più efficiente. –

+3

Sì. Si. Ma sono totalmente d'accordo con te sul fatto che 'if str = ''' è più leggibile e non uso mai 'if Length (str) = 0'. – gabr

+1

La cosa che più mi ha sorpreso è stata la chiamata 'WideString' a' @ WStrEqual' quando si utilizza 'if sw2 = ''. E lavoro molto con 'WideString's quindi questa è davvero una buona informazione per me. – kobik

20

semanticamente essi sono identici e non vi sarà alcuna differenza di prestazioni discernibile. Quindi rimaniamo a guardare alla chiarezza per il lettore del codice.

if Str='' then 

è la versione leggibile a mio parere. Guarda il titolo della tua domanda:

Qual è il modo migliore per verificare una stringa vuota?

Nella tua testa lo vedi come una stringa vuota rispetto alla stringa con lunghezza 0. Quindi scrivi il codice nel modo che corrisponde al tuo punto di vista.

+10

+1 per preferire la leggibilità rispetto alla micro ottimizzazione. – jpfollenius

+0

@Smasher Sembra che gli elettori siano più impressionati dalla prematura micro-ottimizzazione anche se .... ;-) –

+2

+1 da parte mia, tutto ciò che sembra più facile da leggere e non subisce alcuna differenza di prestazioni rispetto a un equivalente può essere solo una buona cosa . –

1

di espandere @gabr's answer, se modifichiamo la fonte per aggiungere i confronti supplementare contro EmptyAnsiStr/EmptyWideStr/EmptyStr, vediamo i seguenti smontaggi da XE1:

Project1.dpr.21: if sa3 = EmptyAnsiStr then 
004111DD A1807E4100  mov eax,[$00417e80] 
004111E2 8B15EC2C4100  mov edx,[$00412cec] 
004111E8 8B12    mov edx,[edx] 
004111EA E83148FFFF  call @LStrEqual 

Project1.dpr.27: if sw3 = EmptyWideStr then 
0041120D A18C7E4100  mov eax,[$00417e8c] 
00411212 8B15E82C4100  mov edx,[$00412ce8] 
00411218 8B12    mov edx,[edx] 
0041121A E8CD49FFFF  call @WStrEqual 

Project1.dpr.33: if su3 = EmptyStr then 
00411236 A1987E4100  mov eax,[$00417e98] 
0041123B 8B15BC2D4100  mov edx,[$00412dbc] 
00411241 8B12    mov edx,[edx] 
00411243 E8DC4CFFFF  call @UStrEqual 

Tutti i 3 richiederà chiamate di funzione.

+0

Lo stesso commento a @gabr che posso ripetere qui, il numero di istruzioni di assemblaggio non significa nulla in un test delle prestazioni, poiché alcune istruzioni sono più veloci di altre. Nel livello basso, spetta al compilatore generare il codice migliore per istruzioni semanticamente equivalenti di alto livello, non il programmatore. –