Какой лучший способ проверить наличие пустой строки в Delphi?

Общим условием, которое должны выполнять все программы, является проверка, является ли строка пустой или нет.

Примите следующие утверждения:

(1)

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

(2)

if Str='' then
  // do something
 Sertac Akyuz16 мая 2012 г., 15:52
@ Андреас - Я тоже!
 François16 мая 2012 г., 20:58
Я считаю, что главное отсутствует: что значит лучше? Это для производительности или читаемости / обслуживания, так как в терминах алгоритма они семантически эквивалентны.
 Andreas Rejbrand16 мая 2012 г., 15:40
Ничего страшного, если вы спросите меня. Они делают то же самое, и никто не быстрее, чем другие.
 Andreas Rejbrand16 мая 2012 г., 15:50
@SertacAkyuz: Действительно, я думаю, что они дадут один и тот же код. Тем не менее, я серьезно не думаю, что производительность здесь является проблемой.
 Sertac Akyuz16 мая 2012 г., 15:48
Второй, кажется, производит меньше кода (одна инструкция CMP).

Ответы на вопрос(3)

Решение Вопроса

В XE2if str = '' компилируется вbetter более быстрый код для строк Ansi и Unicode.if Length(str) = 0 компилируется вbetter более быстрый код для широких строк.

Тестовая программа:

{$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.

Скомпилированный код:

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

Разница еще больше, если оптимизация отключена.

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
 16 мая 2012 г., 17:58
По "лучше" Вы имеете в виду более эффективный.
 16 мая 2012 г., 20:16
Да. Да. Но я полностью согласен с вами, чтоif str = '' более читабелен, и я никогда не используюif Length(str) = 0.
 17 мая 2012 г., 11:41
Больше всего меня удивило то, чтоWideString позвонить@WStrEqual когда используешьif sw2 = '', И я много работаю сWideStringТак что это действительно хорошая информация для меня.
 05 сент. 2014 г., 21:32
Количество инструкций по сборке ничего не значит в тесте производительности (некоторые инструкции выполняются быстрее, чем другие). Лучшее, что вы можете сделать, чтобы получить реальный результат, - это сравнить каждое решение. Но даже это решение странно: именно компилятор генерирует лучший код для семантически эквивалентных высокоуровневых команд, а не для программиста.

Расширить наответ @ gabr, если мы изменим источник, чтобы добавить дополнительные сравнения сEmptyAnsiStr/EmptyWideStr/EmptyStrмы видим следующие разборки из XE1:

Project1.dpr.21: if sa3 = EmptyAnsiStr then
004111DD A1807E4100       mov eax,[$00417e80]
004111E2 8B15EC2C4100     mov edx,[$00412cec]
004111E8 8B12             mov ed,x,[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

Все 3 потребуют вызова функций.

 05 сент. 2014 г., 21:35
Тот же комментарий к @gabr, который я могу повторить здесь, количество инструкций по сборке ничего не значит в тесте производительности, поскольку некоторые инструкции выполняются быстрее, чем другие. На низком уровне, компилятор генерирует лучший код для семантически эквивалентных высокоуровневых инструкций, а не программист.

Семантически они идентичны, и не будет заметной разницы в производительности. Таким образом, мы остаемся понятными для читателя кода.

if Str='' then

это читабельная версия на мой взгляд. Посмотрите на заголовок вашего вопроса:

What is the better way to check for an empty string?

В вашей голове вы видите это как пустую строку, а не строку с длиной 0. Так что пишите код так, чтобы он соответствовал вашей точке зрения.

 16 мая 2012 г., 17:02
+1 за предпочтение удобочитаемости над микрооптимизацией.
 17 мая 2012 г., 03:17
Я использую "если Str = EmptyStr", но я думаю, что это вопрос личных предпочтений
 16 мая 2012 г., 21:04
@ Дэвид, я думаю, что избиратели были впечатлены подробной точностью и кодом. Но реальный вопрос должен заключаться в том, какого рода «лучше». ты должен хотеть. Который приводит ваш ответ в моей книге (хотя я благодарен Габру за дополнительную информацию)
 16 мая 2012 г., 17:08
@Smasher Кажется, что избиратели больше впечатлены преждевременной микрооптимизацией, хотя .... ;-)
 16 мая 2012 г., 20:19
+1 от меня, все, что выглядит проще для чтения и не имеет разницы в производительности по сравнению с аналогом, может быть только хорошей вещью.

Ваш ответ на вопрос