2011-05-12 25 views
6

Estoy usando la reflexión para crear algunos objetos. Los valores que estoy configurando se leen desde un archivo, por lo que están nativamente en formato de cadena y debo convertirlos al tipo de datos de la propiedad.¿Qué es mejor usar: Convert.ToX o X.Parse (...)?

Mi pregunta es, ¿cuál es más rápido/mejor de usar: los métodos Convert.ToX(...) o los métodos X.Parse(...)?

+1

No puedo decírtelo, pero puedo decirte cómo averiguarlo ... Abre ILDasm y abre el dll con todas las clases (lleva un poco de búsqueda) a continuación, puedes ver el código IL que utilizar. No es realmente legible, pero puedes ver lo que está llamando y verificar si en las llamadas que. – Matt

+2

O simplemente use ILSpy para ver el código C# en lugar de las instrucciones IL ... –

+1

posible duplicado de [La diferencia entre convertir y analizar.] (Http://stackoverflow.com/questions/3486810/the-difference-between-convert- y-analizar) –

Respuesta

11

Todas las funciones Convert.ToX que aceptan un argumento de tipo string finalmente llaman al método Parse del tipo de datos apropiado de todos modos.

Por ejemplo, Convert.ToInt32(string) se ve algo como esto:

public static int ToInt32(string value) 
{ 
    if (value == null) 
    { 
     return 0; 
    } 
    return int.Parse(value, CultureInfo.CurrentCulture); 
} 

Lo mismo para todos los demás métodos de conversión numéricas, incluyendo Decimal y DateTime. Así que es bastante irrelevante cuál usas; el resultado (y la velocidad) serán los mismos en ambos casos.

Realmente, la única diferencia es la cláusula de guardia if (value == null) al principio. Si eso es conveniente o no depende del caso de uso específico. Generalmente, si sabe que tiene un objeto no nulo string, también podría usar Parse. Si no está seguro, ConvertToX es una apuesta más segura, ya que requiere menos código de verificación nula en línea.

+0

Buena detective @Cody! Optaré por usar los métodos Convertir, ya que no tengo que preocuparme de buscar nulos. – Micah

+0

Una variable que es nula cuando no lo espero suele ser un error. Por lo tanto, quiero obtener una excepción en lugar de una corrupción de datos silenciosos. Así que diría que tiene que preocuparse más por las comprobaciones nulas cuando usa Convertir que cuando usa el análisis. – CodesInChaos

+0

@Code: Sí, estoy de acuerdo. Pero hay casos en los que no * tienes * una expectativa particular. Sería perfectamente razonable que la variable sea o no sea nula. En ese caso, no hay nada de malo con 'Convert'. –

1

¡Son exactamente lo mismo! Los métodos Convert.ToX(String) realmente llaman a los métodos X.Parse(String).

1

De acuerdo con lo que veo en Reflector, Convertir cadena de formulario es un envoltorio alrededor de Parse. por lo tanto, es razonable razonar que el análisis es marginalmente mejor en el rendimiento.

EDIT: después de Cody señaló que la optimización hará la diferencia casi nada, he probado en mi máquina, y de hecho los tiempos de ejecución para Parse y Convert salió el mismo al analizar 1 millón de inetgers en un bucle.

EDIT2: aquí tienes yas4891, en realidad es el código que usaste con cambios muy pequeños.

public static void Main() 
     { 
      int tRuns = 1000000; 
      List<String> tList = new List<string>(); 
      for (int i = 0; i < tRuns; i++) tList.Add(i.ToString()); 
      Stopwatch s = new Stopwatch(); 
      s.Start(); 
      int tSum = 0; 
      for (int i = tRuns - 1; i >= 0; i--) 
      { 
       tSum += Convert.ToInt32(tList[i]); 
      } 
      s.Stop(); 
      Console.WriteLine("convert: " + s.ElapsedMilliseconds); 

      Console.WriteLine("tSum:" + tSum); 

      s.Reset(); 
      s.Start(); 
      tSum = 0; 
      for (int i = tRuns - 1; i >= 0; i--) 
      { 
       tSum += Int32.Parse(tList[i]); 
      } 
      s.Stop(); 
      Console.WriteLine("parse: " + s.ElapsedMilliseconds); 
      Console.WriteLine("tSum:" + tSum); 
      Console.ReadKey(); 
     } 
+0

La primera parte es más o menos correcta. ¿Pero por qué su conclusión "es razonable"? Eso me indica que son lo mismo, no que uno es "mejor", incluso marginalmente. –

+0

@Cody Gray tienes razón, no estaba claro aquí, actualicé la respuesta – Menahem

+0

Eso tampoco es correcto. Supuse que era hacia donde ibas, pero una vez que el compilador de JIT finaliza con el código, es muy poco probable que exista * cualquier * diferencia de rendimiento perceptible entre los dos métodos. –

-1

usando el siguiente código

int tRuns = 1000000; 
List<String> tList = new List<string>(); 

for (int i = 0; i < tRuns; i++) 
    tList.Add(i.ToString()); 


PerformanceMeter.Start(); 
int tSum = 0; 
for (int i = tRuns-1; i >= 0; i--) 
{ 
    tSum += Convert.ToInt32(tList[i]); 
} 

PerformanceMeter.LogAndStop("using Convert.ToInt32:"); 

cLogger.Info("tSum:" + tSum); 
PerformanceMeter.Start(); 

tSum = 0; 
for (int i = tRuns-1; i >= 0; i--) 
{ 
    tSum += Int32.Parse(tList[i]); 
} 

PerformanceMeter.LogAndStop("using Int32.Parse:"); 
cLogger.Info("tSum:" + tSum); 

me da el siguiente resultado:

{} PerformanceMeter: 178 INFORMACIÓN: - utilizando Convert.ToInt32 :: 233,0133 ms
{Programa}: 92 INFO: - tSum: 1783293664
{PerformanceMeter}: 178 INFO: - usando Int32.Parse :: 179,0103 ms
{Programa}: 102 INFORMACIÓN: - tSUM: 1783293664

Así al menos para Int32 parece ser más eficaz utilizar Int32.Parse. Sin embargo, esto puede ser diferente en su escenario y supongo que debe hacer una prueba similar.

+0

Erm, no intentó seriamente probar el rendimiento de algo cuando se compiló en el modo "Debug" ** con las optimizaciones desactivadas **, ¿verdad? Es una prueba ** completamente sin sentido. Lo bueno es que no tengo votos para el día, este es un sencillo -1. –

+0

@Cody: ¿solo porque utilicé salidas de depuración para este rápido ejemplo? Para que lo entiendas: hice esta prueba rápida en uno de mis programas que está configurado en 'Liberar' y utilizo las salidas de DETENCIÓN de log4net incluso en mis lanzamientos – yas4891

+0

Sí. Las partes audaces de mi comentario son importantes. El modo de depuración desactiva todas las optimizaciones de código, incluido, entre otros, el compilador JIT. El resultado son datos sin sentido que se alinean con sus intuiciones, pero no se mantienen una vez que se aplican las optimizaciones. Hacer pruebas de rendimiento con el código de depuración muestra un malentendido fundamental de los propósitos para cada uno. –

1

Otra posibilidad es los métodos TryParse. Estos son particularmente útiles si existe la posibilidad de que el valor no se pueda analizar con éxito.En lugar de lanzar una excepción, la llamada devolverá un bool indicando si la operación fue exitosa. Esto se ejecuta mucho más rápido y es una implementación más limpia en comparación con tratar con la excepción.

Cuestiones relacionadas