Сведения о вопросе

Fhohir

21:06, 1st October, 2020

Проверка содержимого строки? длина строки Против пустой строки

Просмотров: 530   Ответов: 13

Что более эффективно для компилятора и как лучше всего проверить, является ли строка пустой?

  1. Проверка, соответствует ли длина строки = = 0
  2. Проверка пустоты строки (strVar == "")

Кроме того, зависит ли ответ от языка?



  Сведения об ответе

PHPH

11:01, 24th August, 2020

Да, это зависит от языка, так как хранение строк отличается между языками.

  • Pascal-тип строки: Length = 0 .
  • Строки в стиле C: [0] == 0 .
  • .
  • NET: .IsNullOrEmpty .

И т.д.


  Сведения об ответе

LAST

21:32, 10th August, 2020

В языках, использующих строки C-style (null-terminated), сравнение с "" будет быстрее. Это операция O (1), в то время как длина строки в стиле C равна O(n).

В языках, хранящих длину как часть строкового объекта (C#, Java,...) проверка длины также O (1). В этом случае непосредственная проверка длины выполняется быстрее, поскольку это позволяет избежать накладных расходов при построении новой пустой строки.


  Сведения об ответе

ASSembler

01:15, 7th August, 2020

в сетях:

string.IsNullOrEmpty( nystr );

строки могут быть null, поэтому .Length иногда выбрасывает NullReferenceException


  Сведения об ответе

PHPH

15:44, 15th August, 2020

В языках, использующих строки C-style (null-terminated), сравнение с "" будет быстрее

На самом деле, может быть, лучше проверить, является ли первый символ в строке '\0':

char *mystring;
/* do something with the string */
if ((mystring != NULL) && (mystring[0] == '\0')) {
    /* the string is empty */
}

В Perl есть третий вариант, что строка не определена. Это немного отличается от указателя NULL в C, хотя бы потому, что вы не получаете ошибки сегментации для доступа к неопределенной строке.


  Сведения об ответе

ITSME

09:11, 2nd August, 2020

Предполагая, что ваш вопрос таков .NET:

Если вы хотите проверить свою строку на наличие nullity, также используйте IsNullOrEmpty, если вы уже знаете, что ваша строка не является null, например, при проверке TextBox.Text и т. д., не используйте IsNullOrEmpty, и тогда придет ваш вопрос.
Так что, на мой взгляд, String.Length-это меньшая производительность, чем сравнение строк.

I event протестировал его (я также протестировал с C#, тем же результатом):

Module Module1
  Sub Main()
    Dim myString = ""


    Dim a, b, c, d As Long

    Console.WriteLine("Way 1...")

    a = Now.Ticks
    For index = 0 To 10000000
      Dim isEmpty = myString = ""
    Next
    b = Now.Ticks

    Console.WriteLine("Way 2...")

    c = Now.Ticks
    For index = 0 To 10000000
      Dim isEmpty = myString.Length = 0
    Next
    d = Now.Ticks

    Dim way1 = b - a, way2 = d - c

    Console.WriteLine("way 1 took {0} ticks", way1)
    Console.WriteLine("way 2 took {0} ticks", way2)
    Console.WriteLine("way 1 took {0} ticks more than way 2", way1 - way2)
    Console.Read()
  End Sub
End Module

Результат:

Way 1...
Way 2...
way 1 took 624001 ticks
way 2 took 468001 ticks
way 1 took 156000 ticks more than way 2

Это означает, что сравнение занимает гораздо больше времени, чем проверка длины строки.


  Сведения об ответе

dumai

05:01, 9th August, 2020

В Java 1.6 класс String имеет новый метод isEmpty

Существует также библиотека Jakarta commons, которая имеет метод isBlank . Пробел определяется как строка, содержащая только whitespace.


  Сведения об ответе

lourence

01:32, 4th August, 2020

String.IsNullOrEmpty() работает только на .net 2.0 и выше, для .net 1/1.1 я обычно использую:

if (inputString == null || inputString == String.Empty)
{
    // String is null or empty, do something clever here. Or just expload.
}

Я использую String.Empty в отличие от "" Потому что "" создаст объект, в то время как String.Empty не будет - я знаю, что это что-то маленькое и тривиальное, но я все еще предпочитаю не создавать объекты, когда они мне не нужны! ( Источник )


  Сведения об ответе

COOL

13:30, 4th August, 2020

На самом деле, IMO лучший способ определить-это метод IsNullOrEmpty() класса string.

http://msdn.microsoft.com/en-us/library/system.string.isnullorempty.

Update: я предположил, что .Net, на других языках, это может быть по-другому.


  Сведения об ответе

LIZA

19:13, 9th August, 2020

В этом случае непосредственная проверка длины выполняется быстрее, поскольку это позволяет избежать накладных расходов при построении новой пустой строки.

- Это не всегда так. ""является строковым литералом, поэтому в Java он почти наверняка уже будет интернирован.


  Сведения об ответе

DO__IT

13:37, 3rd August, 2020

Для строк C,

if (s[0] == 0)

будет быстрее, чем любой из них

if (strlen(s) == 0)

или

if (strcmp(s, "") == 0)

потому что вы избежите накладных расходов при вызове функции.


  Сведения об ответе

KOMP

07:53, 22nd August, 2020

@Nathan

На самом деле, может быть, лучше проверить, является ли первый символ в строке '\0':

Я почти упомянул об этом, но в итоге оставил его, так как вызов strcmp() с пустой строкой и прямая проверка первого символа в строке-это оба O(1). Вы в основном просто платите за дополнительный вызов функции, что довольно дешево. Если вам действительно нужна абсолютная лучшая скорость, то определенно идите с прямым сравнением first-char-to-0.

Честно говоря , я всегда использую strlen() == 0, потому что я никогда не писал программу, где это было бы действительно измеримой проблемой производительности, и я думаю, что это самый читаемый способ выразить чек.


  Сведения об ответе

DAAA

04:15, 24th August, 2020

Опять же, не зная языка, это невозможно сказать.

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

Я бы рекомендовал написать функцию, которая явно делает то, что вы хотите, например

#define IS_EMPTY(s) ((s)[0]==0)

или сравнимы. Теперь нет никаких сомнений в том, что вы проверяете.


  Сведения об ответе

darknet

15:55, 10th August, 2020

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

Рассмотреть следующее.

strInstallString    "1" string

Все это копируется из окна locals отладчика Visual Studio. Одно и то же значение используется во всех трех следующих примерах.

если бы ... ( strInstallString == "" ) === если ( strInstallString == string.Empty )

Ниже приведен код, отображаемый в окне дизассемблирования отладчика Visual Studio 2013 для этих двух принципиально идентичных случаев.

if ( strInstallString == "" )
003126FB  mov         edx,dword ptr ds:[31B2184h]
00312701  mov         ecx,dword ptr [ebp-50h]
00312704  call        59DEC0B0            ; On return, EAX = 0x00000000.
00312709  mov         dword ptr [ebp-9Ch],eax
0031270F  cmp         dword ptr [ebp-9Ch],0
00312716  sete        al
00312719  movzx       eax,al
0031271C  mov         dword ptr [ebp-64h],eax
0031271F  cmp         dword ptr [ebp-64h],0
00312723  jne         00312750

if ( strInstallString == string.Empty )
00452443  mov         edx,dword ptr ds:[3282184h]
00452449  mov         ecx,dword ptr [ebp-50h]
0045244C  call        59DEC0B0        ; On return, EAX = 0x00000000.
00452451  mov         dword ptr [ebp-9Ch],eax
00452457  cmp         dword ptr [ebp-9Ch],0
0045245E  sete        al
00452461  movzx       eax,al
00452464  mov         dword ptr [ebp-64h],eax
00452467  cmp         dword ptr [ebp-64h],0
0045246B  jne         00452498

если ( strInstallString == string.Empty) существенно не отличается

if ( strInstallString.Length == 0 )
003E284B  mov         ecx,dword ptr [ebp-50h]
003E284E  cmp         dword ptr [ecx],ecx
003E2850  call        5ACBC87E        ; On return, EAX = 0x00000001.
003E2855  mov         dword ptr [ebp-9Ch],eax
003E285B  cmp         dword ptr [ebp-9Ch],0
003E2862  setne       al
003E2865  movzx       eax,al
003E2868  mov         dword ptr [ebp-64h],eax
003E286B  cmp         dword ptr [ebp-64h],0
003E286F  jne         003E289C

Из приведенных выше списков машинного кода, созданных модулем NGEN фреймворка .NET, версия 4.5, я делаю следующие выводы.

  1. Проверки на равенство против пустой строковый литерал и статического string.Empty собственность на класс System.string, для всех практических целей, идентичны. Единственное различие между двумя фрагментами кода - это источник первой инструкции перемещения, и оба они являются смещениями относительно ds, подразумевая, что оба относятся к запеченным константам.

  2. Проверка на равенство с пустой строкой, как литералом или свойством string.Empty, устанавливает вызов функции с двумя аргументами, который указывает на inequality , возвращая ноль. Я основываю этот вывод на других тестах, которые я провел пару месяцев назад, в которых я следовал за некоторыми из моих собственных кодов через раздел управляемого/неуправляемого и обратно. Во всех случаях любой вызов, требующий двух или более аргументов, помещает первый аргумент в регистр ECX, а второй-в регистр EDX. Я не помню, как передавались последующие аргументы. Тем не менее, настройка вызова больше походила на __fastcall, чем на __stdcall. Кроме того, ожидаемые возвращаемые значения всегда показывались в регистре EAX, который является почти универсальным.

  3. Проверка длины строки настраивает вызов функции с одним аргументом, который возвращает 1 (в регистре EAX), что соответствует длине проверяемой строки.

  4. Учитывая, что непосредственно видимый машинный код почти идентичен, единственная причина, по которой я могу предположить, что это объясняет лучшую производительность равенства строк по длине sting, о которой сообщает Shinny, заключается в том, что функция с двумя аргументами, выполняющая сравнение, значительно лучше оптимизирована, чем функция с одним аргументом, считывающая длину экземпляра строки.

Вывод

В принципе, я избегаю сравнения с пустой строкой как литералом, потому что пустой строковый литерал может показаться неоднозначным в исходном коде. С этой целью мои .NET вспомогательные классы уже давно определили пустую строку как константу. Хотя я использую string.Empty для прямых, встроенных сравнений, константа зарабатывает свое содержание для определения других констант, значение которых является пустой строкой, потому что константа не может быть назначена string.Empty в качестве ее значения.

Это упражнение раз и навсегда устраняет все мои опасения относительно стоимости сравнения с string.Empty или константой, определенной моими вспомогательными классами.

Однако это также вызывает озадачивающий вопрос, чтобы заменить его; почему сравнение с string.Empty более эффективно, чем проверка длины строки? Или это тест используется Шинни признан недействительным, потому что по способу реализации цикла? (Мне трудно в это поверить, но, с другой стороны, меня и раньше обманывали, как, я уверен, и вас тоже!)

Я уже давно предположил, что system.string объекта были подсчитанными строками, фундаментально похожими на давно установленную базовую строку (BSTR), которую мы давно знаем из COM.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться