2009-12-29 16 views
7

Tengo una declaración en la que se le asigna una cadena de la siguiente manera:Concatenación de cadenas con o sin .ToString()?

for (int i = 0; i < x; i++) 
{ 
    Foo.MyStringProperty = "Bar_" + i.ToString(); 
    /* ... */ 
} 

¿Hay diferencias de rendimiento entre i.ToString() o simplemente i, ya que ambos se acaba de convertir a la (referencia cultural de todos?) De cadena equivalente?

Soy muy consciente de la existencia de String.Concat(), String.Format, StringBuilder, etc., pero por el bien de este caso, supongamos que sólo pueden utilizar + concatenación.

Gracias de antemano.

+3

¿no puede hacer una aplicación de prueba? Déjalo repetir por 10.000 veces, mida el tiempo y sepa la respuesta. – Natrium

+3

Advertencia: 'ToString()' usa la cultura actual. Si desea una conversión independiente de la cultura, debe usar 'ToString (CultureInfo.InvariantCulture)' (Esto es más importante cuando se trata de números de coma flotante que con enteros). –

Respuesta

23

+ concatenación utiliza String.Concat de todos modos - String en sí mismo no expone un operador +.

Así, por ejemplo:

int i = 10; 
string x = "hello" + i; 

se compila en:

int i = 10; 
object o1 = "hello"; 
object o2 = i; // Note boxing 
string x = string.Concat(o1, o2); 

, mientras que llamar directamente ToString evitará el boxeo y llamar a la sobrecarga de Concat(string, string). Por lo tanto, la versión con la llamada ToString será ligeramente más más eficiente, pero dudo mucho que sea significativa, y le recomiendo encarecidamente que elija la versión que considere más legible.

+0

Gracias, respuesta muy clara. Aunque estaría tentado de aceptar el comentario de Divo si fuera una respuesta, debido a su advertencia sobre la información cultural. – Webleeuw

+0

Al probar el boxeo y el desempaquetado de un tipo de valor cuando NO se utiliza el método ToString, se produce un golpe de rendimiento de aproximadamente 2,5%. – Firestrand

+1

Interesante. Pensé que tal vez el compilador de C# generaría la misma IL en las dos situaciones, pero tienes razón, no (tampoco con C# 5). La situación con un tipo de referencia es un poco diferente. Aquí el código '" hello "+ obj' no arrojará aunque' obj' sea una referencia nula. Pero '" hello "+ obj.ToString()' lanzará si 'obj' es nulo, por supuesto. Sin embargo, incluso con tipos de referencia, el estilo con '.ToString()' explícito podría ser teóricamente más rápido (cuando 'obj' no es nulo) porque utiliza la sobrecarga' Concat (cadena, cadena) 'en lugar del' Concat (objeto , objeto) 'sobrecarga. –

7

El solo uso de string + object fuerza una llamada a ToString() en el objeto; es equivalente a llamarlo explícitamente.

+3

@Aviad: Sin embargo, hay una diferencia en el tiempo, lo que afecta si el valor está encasillado o no. –

1

Usaría .ToString() por costumbre y legibilidad, estoy seguro de que encontrará un mejor rendimiento al ahorrar en otro lugar.

3

ToString es el método predeterminado utilizado para escribir un objeto. Entonces, si usa "i" o "i.ToString()" es lo mismo.

Si conoce un poco acerca de la sobrecarga del operador en C++, puede entender cómo funciona "+" en este caso.

using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.IO; 
using System.Text; 


public class MainClass 
{ 
    public static void Main() 
    { 
     int number = 10; 
     string msg = "age is " + number + "."; 
     msg += " great?"; 
     Console.WriteLine("msg: {0}", msg); 

     String s1 = 10 + 5 + ": Two plus three is " + 2 + 3; 
     String s2 = 10 + 5 + ": Two plus three is " + (2 + 3); 
     Console.WriteLine("s1: {0}", s1); 
     Console.WriteLine("s2: {0}", s2); } 

} 

Resultado: msg: la edad es 10. grande?

s1: 15: Dos más tres es 23

s2: 15: Dos más tres es 5

0
for(int i = 0; i < x; i++) { 
    Foo.MyStringProperty = "Bar_" + i.ToString(); 
    [...] 
} 

Desde aquí su resultante es en cadena e i es int, por lo que "barra _" + estaré concatenado y llamaré a .ToString() para que el objeto se adjunte con una cadena. respecto al rendimiento que puede utilizar algunas herramientas de medición del rendimiento

Yo generalmente uso de fundición, si tengo dos objetos diff

+0

vote bueno o malo si resuelve su problema –

0

Como ya se ha mencionado por Jon Skeet, el punto sobre el boxeo es muy importante!

Si usa explícitamente ToString() no hay boxeo, lo que significa que no se crea ningún objeto-cuadro alrededor de i. El Garbage Collector debe desechar el objeto de la caja alrededor de ti más tarde, lo que provoca una penalización de rendimiento.

Si lo hace solo unas pocas veces en su programa, no importa, pero si está boxeando muy a menudo, debe ir a la versión ToString().

Cuestiones relacionadas