Respuesta

15

Sí, depende de la lengua, ya que el almacenamiento cadena difiere entre las lenguas.

  • Pascal-tipo cadenas: Length = 0.
  • cadenas estilo C: [0] == 0.
  • .NET: .IsNullOrEmpty.

Etc.

+2

Creo que OP estaba preguntando sobre la validación de cadenas en blanco, no la nulidad, por lo que cuando ya sabe que la cadena no es nula, usar IsNullOrEmpty es simplemente otra verificación innecesaria. Entonces, la pregunta del OP es lo que requiere más rendimiento, myString.Length> 0 o myString! = "". Lee http://stackoverflow.com/questions/10230/checking-for-string-contents-string-length-vs-empty-string/2306659#2306659 – Shimmy

2

En .Net:

string.IsNullOrEmpty(nystr); 

cuerdas pueden ser nulos, por lo .length veces lanza una NullReferenceException

13

En lenguajes que usan C-estilo cuerdas (terminadas en cero), en comparación con "" será más rápido. Esa es una operación O (1), mientras que tomar la longitud de una cadena de estilo C es O (n).

En lenguajes que almacenan longitud que parte del objeto de cadena (C#, Java, ...) comprobación de la longitud es también O (1). En este caso, la comprobación directa de la longitud es más rápida, ya que evita la sobrecarga de la construcción de la nueva cadena vacía.

+3

En C#, si lo comparas con string.Empty, entonces eres tú estamos comparando contra una cadena ya construida. Entonces es O (1) también. –

1

En Java 1.6, la clase String tiene un nuevo método isEmpty

También existe la biblioteca Commons Yakarta, que tiene el método isBlank. Blanco se define como una cadena que contiene solo espacios en blanco.

0

En este caso, la comprobación directa de la longitud es más rápida, ya que evita la sobrecarga de la construcción de la nueva cadena vacía.

@DerekPark: Eso no siempre es cierto. "" es un literal de cadena, por lo que, en Java, casi con certeza ya estará internado.

0

Para cadenas de C,

if (s[0] == 0) 

será más rápido que cualquiera

if (strlen(s) == 0) 

o

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

porque se evitará la sobrecarga de una llamada a la función.

2

En lenguajes que usan C-estilo cuerdas (terminadas en cero), en comparación con "" será más rápido

En realidad, puede ser mejor para comprobar si el primer carácter de la cadena es ' \ 0 ':

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

En Perl hay una tercera opción, que la cadena no está definida. Esto es un poco diferente de un puntero NULL en C, aunque solo sea porque no se obtiene un error de segmentación para acceder a una cadena indefinida.

0

@ Nathan

En realidad, puede ser mejor para comprobar si el primer carácter de la cadena es '\ 0':

Casi mencionado, pero terminó dejando fuera , ya que llamar al strcmp() con la cadena vacía y verificar directamente el primer carácter en la cadena son ambos O (1). Básicamente, solo paga por una llamada de función extra, que es bastante barata. Si usted realmente necesita la mejor velocidad absoluta, sin embargo, definitivamente vaya con una primera comparación directa de char-a-0.

Honestamente, yo siempre utilizar strlen() == 0, porque tengo Nunca escrito un programa en el que esto era en realidad un problema de rendimiento medible, y creo que esa es la forma más legible para expresar el cheque.

1

String.IsNullOrEmpty() sólo funciona en .NET 2,0 y por encima, para .NET 1/1,1, que tienden a utilizar:

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

utilizo String.Empty en contraposición a "", porque "" creará un objeto , mientras que String.Empty no: sé que es algo pequeño y trivial, pero todavía no creo objetos cuando no los necesito. (Source)

+0

Me sorprendería mucho si "" en realidad resulta en una instanciación dentro del compilador C#. – jsight

+1

Use 'inputString.Length == 0', en lugar de 'inputString == String.Empty' para un mejor rendimiento –

+0

Id argumento que inputString == String.Empty es más fácil de leer que .Length == 0 ... –

0

De nuevo, sin saber el idioma, es imposible de decir.

Sin embargo, le recomiendo que elija la técnica que tenga más sentido para el programador de mantenimiento que sigue y deberá mantener su trabajo.

lo recomiendo escribir una función que explícitamente lo que quiere, como

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

o comparable. Ahora no hay dudas en que lo estás verificando.

1

Suponiendo que tu pregunta es.NET:

Si quiere validar su cadena contra la nulidad, use IsNullOrEmpty, si ya sabe que su cadena no es nula, por ejemplo, al revisar TextBox.Text, etc., no use IsNullOrEmpty, y luego ingrese tu pregunta.
Por lo tanto, para mi opinión String.Length es menos rendimiento que la comparación de cadenas.

caso he comprobado (También he probado con C#, mismo resultado):

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 

Resultado:

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

Lo que significa comparación tiene mucho más de lo cheque longitud de la cadena.

+0

Sin embargo, en .Net puede evitar la comparación explícita de cadenas comparando contra cadenas. Vacío en lugar de la cadena vacía (""). Eso debería convertirlo en una operación O (1). –

+0

Creo que string.Empty es exactamente el mismo literal que "", realmente no entiendo la diferencia. – Shimmy

+0

string.Empty es una instancia de la clase de cadena cuyo valor es "". Sin embargo, la sobrecarga de cadena para Equals y (==) hará una comparación de referencia antes de que haga un personaje para la comparación de caracteres. Si las referencias son iguales que la comparación de caracteres se omite. Entonces, comparar un valor que sea string.Empty to string.Empty será significativamente más rápido que compararlo con "", lo que generará un nuevo objeto de cadena y establecerá su valor inicial en "". Ellos no son lo mismo. –

0

Después de leer este hilo, realicé un pequeño experimento, que arrojó dos hallazgos distintos e interesantes.

Considere lo siguiente.

strInstallString "1" string 

Lo anterior se copia de la ventana local del depurador de Visual Studio. El mismo valor se usa en los tres ejemplos siguientes.

si (strInstallString == "") === si (== strInstallString String.Empty)

A continuación se presenta el código que aparece en la ventana de desmontaje del depurador de Visual Studio 2013 para estos dos fundamentalmente idéntica casos.

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 

si (== strInstallString String.Empty) no es significativamente diferente

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 

A partir de los listados de código de máquina por encima, generada por el módulo NGEN de .NET Framework, versión 4.5 , Saco las siguientes conclusiones.

  1. Las pruebas para la igualdad frente a la cadena vacía literal y la propiedad String.Empty estática en la clase System.string son, a todos los efectos prácticos, idéntico. La única diferencia entre los dos fragmentos de código es la fuente de la primera instrucción de movimiento, y ambos son desplazamientos relativos a ds, lo que implica que ambos se refieren a las constantes de cocción.

  2. Las pruebas para la igualdad frente a la cadena vacía, ya sea como un literal o la propiedad String.Empty, establece una llamada a una función de dos argumentos, lo que indica la desigualdad devolviendo cero. Baso esta conclusión en otras pruebas que realicé hace un par de meses, en las que seguí parte de mi propio código a través de la división gestionada/no gestionada y viceversa. En todos los casos, cualquier llamada que requiera dos o más argumentos colocará el primer argumento en el registro ECX, y el segundo en el registro EDX. No recuerdo cómo se aprobaron los argumentos posteriores. Sin embargo, la configuración de la llamada se parecía más a __fastcall que __stdcall. Del mismo modo, los valores esperados de retorno siempre aparecían en el registro EAX, que es casi universal.

  3. Al probar la longitud de la cadena se configura una llamada de función de un argumento, que devuelve 1 (en el registro EAX), que es la longitud de la cadena que se está probando.

  4. Teniendo en cuenta que el código máquina inmediatamente visible es casi idéntica, la única razón que puedo imaginar que explicaría el mejor rendimiento de la igualdad de cadenas sobre la longitud picadura informado por Shinny es que la función de dos argumentos que realiza la comparación se optimiza significativamente mejor que la función de un argumento que lee la longitud de la instancia de cadena.

Conclusión

Como cuestión de principio, puedo evitar la comparación con la cadena vacía como un literal, ya que la cadena vacía literal puede parecer ambigua en el código fuente. Para ese fin, mis clases de ayuda .NET han definido la cadena vacía como una constante. Aunque uso string.Empty para comparaciones directas, en línea, la constante gana su mantenimiento para definir otras constantes cuyo valor es la cadena vacía, porque no se puede asignar una constante string.Empty como su valor.

Este ejercicio soluciona, de una vez por todas, cualquier preocupación que pueda tener acerca del costo, si lo hubiera, de comparar string.Empty o la constante definida por mis clases de ayuda.

Sin embargo, también plantea una pregunta desconcertante para reemplazarlo; ¿Por qué comparar con string.Empty es más eficiente que probar la longitud de la cadena? ¿O la prueba utilizada por Shinny es invalidada debido a la forma en que se implementa el ciclo? (Me parece que es difícil de creer, pero, de nuevo, me han engañado antes, como estoy seguro de que usted tiene, también!)

que han asumido durante mucho tiempo que las cadenas System.string objetos se contaron, fundamentalmente similar a la cadena básica largamente establecida (BSTR) que conocemos desde hace mucho tiempo por COM.

Cuestiones relacionadas