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