toint32 - parse bool to int c#
¿Qué es más rápido:(int), Convert.ToInt32(x) o Int32.Parse(x)? (15)
¿Cuál de los siguientes códigos es el más rápido / la mejor práctica para convertir algún objeto x?
int myInt = (int)x;
o
int myInt = Convert.ToInt32(x);
o
int myInt = Int32.Parse(x);
o en el caso de una cadena ''s''
int myInt;
Int32.TryParse(s, out myInt);
Tengo curiosidad sobre cuál es el más rápido para tipos de datos que tienen un método en Convert, no solo en ints. Acabo de usar int como ejemplo.
Editar: Este caso surgió al obtener información de una tabla de datos. Will (int) aún funciona más rápido?
De algunas pruebas, cuando el objeto x = 123123123, int realiza el más rápido, como muchos han dicho. Cuando x es una cadena, Parse ejecuta el más rápido (nota: el reparto arroja una excepción). Lo que realmente me interesa es cómo se ejecutan cuando se recupera el valor de la siguiente manera:
foreach(DataRow row in someTable.Rows)
{
myInt = (int)row["some int value"];
myInt2 = Int.Parse(row["some int value"]);
myInt2 = Convert.ToInt32(row["some int value"]);
}
Depende de lo que esperas x ser
Si x es un int encuadrado, entonces (int)x
es el más rápido.
Si x es una cadena pero definitivamente es un número válido, entonces int.Parse(x)
es el mejor
Si x es una cadena pero puede que no sea válida, int.TryParse(x)
es mucho más rápido que un bloque try-catch.
La diferencia entre Parse y TryParse es insignificante en todos excepto en los bucles más grandes.
Si no sabe qué es x (tal vez una cadena o un int Convert.ToInt32(x)
) entonces Convert.ToInt32(x)
es lo mejor.
Estas reglas generalizadas también son válidas para todos los tipos de valores con métodos estáticos Parse y TryParse.
¿Por qué no lo pruebas un par de miles de veces?
(Esto vale para todas las preguntas "¿Qué es más rápido:")
Hmmm, muchos votos negativos a lo largo de los años ... Creo que debería ampliar esta respuesta.
La declaración anterior se hizo con cierto grado de ligereza en mi juventud, sin embargo, aún estoy de acuerdo con su opinión. No vale la pena perder tiempo creando una pregunta de SO, preguntándole a los demás qué creen que es más rápido de dos o tres operaciones que toman menos de 1ms cada una.
El hecho de que uno pueda tomar un ciclo o dos más que el otro casi con certeza será insignificante en el uso diario. Y si alguna vez nota un problema de rendimiento en su aplicación cuando está convirtiendo millones de objetos en ints, ese es el punto donde puede crear un perfil del código real , y podrá probar fácilmente si la conversión int es realmente el cuello de botella.
Y mientras que hoy es el convertidor object-int, mañana tal vez creas que tu objeto: el convertidor DateTime está tardando mucho tiempo. ¿Crearías otra pregunta de SO para averiguar cuál es el método más rápido?
En cuanto a su situación (sin duda ya se resolvió por mucho tiempo), como se menciona en un comentario, está consultando una base de datos, por lo que la conversión de objeto-int es la menor de sus preocupaciones. Si yo fuera usted, usaría cualquiera de los métodos de conversión que mencionó. Si surge un problema, aislaría la llamada, usando un generador de perfiles o registro. Luego, cuando noto que la conversión de object-int se realiza un millón de veces y el tiempo total que toma esa conversión parece relativamente alto, cambiaría a usar un método de conversión y un perfil diferente. Elija el método de conversión que requiera menos tiempo. Incluso podría probar esto en una solución separada, o incluso LINQPad, o Powershell, etc.
Al final, todos terminan llamando:
System.Number.ParseInt32(string s, NumberStyles style, NumberFormatInfo info);
Entonces, en resumen, no habrá diferencia alguna.
Eche un vistazo en .Net Reflector para ver esto.
Al optimizar una cuadrícula de datos encuadernada en .Net 2, descubrí que casi la mitad del tiempo se empleó en los métodos ToString () de varios objetos que luego se usaron como entradas de las operaciones Convertir. Al aislar estos casos y enviarlos al tipo correcto cuando sea posible (dado que eran filas extraídas de una base de datos y se podía confiar en los tipos), esto causó un aumento masivo en la velocidad de esa operación de enlace de datos.
Por lo tanto, si conoce el tipo de cosas por adelantado y le da al código la cantidad de veces suficiente, vale la pena el esfuerzo de lanzarlo directamente en lugar de convertirlo cuando sea necesario.
Alguien ya hizo la evaluación comparativa. Aquí están los resultados. La manera más rápida si sabes lo que estás convirtiendo siempre será una int válida, es usar el siguiente método (que algunas personas han respondido anteriormente):
int value = 0;
for (int i = 0; i < str.Length; i++)
{
value = value * 10 + (str[i] - ''0'');
}
Otras técnicas que se compararon fueron:
- Convert.ToInt32
- Int32.TryParse
- int.Parse
Cuando tengo preguntas sobre las diferencias de rendimiento entre las diferentes formas de hacer algo específico como este, suelo hacer una nueva entrada en mi copia de MeasureIt, una descarga gratuita de un gran artículo de MSDN de Vance Morrison. Para obtener más información, consulte el artículo.
Al agregar un simple código a MeasureIt, obtengo los resultados a continuación que comparan los tiempos reales de los diversos métodos de conversión a int. Tenga en cuenta que el lanzamiento de string a int arrojará una excepción y no es válido, así que solo agregué las permutaciones que tenían sentido para mí.
Name Median Mean StdDev Min Max Samples IntCasts: Copy [count=1000 scale=10.0] 0.054 0.060 0.014 0.054 0.101 10 IntCasts: Cast Int [count=1000 scale=10.0] 0.059 0.060 0.007 0.054 0.080 10 IntCasts: Cast Object [count=1000 scale=10.0] 0.097 0.100 0.008 0.097 0.122 10 IntCasts: int.Parse [count=1000 scale=10.0] 2.721 3.169 0.850 2.687 5.473 10 IntCasts: Convert.ToInt32 [count=1000 scale=10.0] 3.221 3.258 0.067 3.219 3.418 10
Para encontrar el mejor rendimiento para los diferentes tipos que le interesan, simplemente extienda el código a continuación, que es literalmente todo lo que tuve que agregar a MeasureIt para generar la tabla anterior.
static unsafe public void MeasureIntCasts()
{
int result;
int intInput = 1234;
object objInput = 1234;
string strInput = "1234";
timer1000.Measure("Copy", 10, delegate
{
result = intInput;
});
timer1000.Measure("Cast Object", 10, delegate
{
result = (int)objInput;
});
timer1000.Measure("int.Parse", 10, delegate
{
result = int.Parse(strInput);
});
timer1000.Measure("Convert.ToInt32", 10, delegate
{
result = Convert.ToInt32(strInput);
});
}
Extendiendo la prueba de Eric Cosky por alternativas de Sam Allen , encontré que si sabes que tu cadena es un número entero válido, entonces analizarlo tú mismo es mucho más rápido.
Extendí la prueba por los siguientes casos:
timer1000.Measure("IntParseFast", 10, delegate
{
result = Misc.IntParseFast(strInput);
});
timer1000.Measure("IntParseUnsafe", 10, delegate
{
result = Misc.IntParseUnsafe(strInput);
});
Con las siguientes implementaciones:
public static int IntParseFast(string value)
{
int result = 0;
int length = value.Length;
for (int i = 0; i < length; i++)
{
result = 10 * result + (value[i] - 48);
}
return result;
}
public unsafe static int IntParseUnsafe(string value)
{
int result = 0;
fixed (char* v = value)
{
char* str = v;
while (*str != ''/0'')
{
result = 10 * result + (*str - 48);
str++;
}
}
return result;
}
Obtengo los siguientes resultados:
IntCaint.Parse 5,495
IntCaConvert.ToInt32 5,653
IntCaIntParseFast 1,154
IntCaIntParseUnsafe 1,245
La conversión (int) en cadena no funcionará, así que no la pruebo. Convert.ToInt32 refleja como probar el valor de nulo y ENTONCES llamar a int.Parse, por lo que, en general, debería ser más lento que int.Parse ().
La mejor práctica sería TryParse, y ver el resultado de eso, si funcionó; de lo contrario, podría obtener excepciones.
No estoy seguro sobre el rendimiento, pero estos métodos no son los mismos en absoluto. Tanto Parse
como TryParse
funcionan con una cadena, la representación de String
de un objeto se analiza (vea MSDN).
Convierte la representación de cadena de un número en su entero equivalente con signo de 32 bits.
No estoy seguro sobre el casting y la clase Convert
, pero el cast es solo para objetos que ya son enteros de hecho pero no fuertemente tipados.
Matthias
Si sabe que los datos son definitivamente int, entonces int myInt = (int)x;
debería ser la opción más rápida. De TryParse
contrario, TryParse
te ayudará a hacerlo bien sin la lentitud de las excepciones.
Por cierto:
(int) solo unboxes por lo tanto más rápido,
(int) IL =
.locals init (
[0] object x,
[1] int32 Y)
L_0000: ldc.i4.1
L_0001: box int32
L_0006: stloc.0
L_0007: ldloc.0
L_0008: unbox int32
L_000d: ldobj int32
L_0012: stloc.1
L_0013: ret
Convert.Toint32 =
.locals init (
[0] object x,
[1] int32 Y)
L_0000: ldc.i4.1
L_0001: box int32
L_0006: stloc.0
L_0007: ldloc.0
L_0008: call object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
L_000d: call int32 [mscorlib]System.Convert::ToInt32(object)
L_0012: stloc.1
L_0013: ret
Si tuviera la necesidad de la velocidad extra, sería fácil probar las diferentes opciones diferentes. Como no los está probando, no debe necesitarlos. ¡No pierdas tu tiempo con micro optimizaciones sin sentido!
esto no es verdad. La conversión rápida es directo:
int i = (int) stringData;
watch.Elapsed = {00:00:00.1732388}
watch2.Elapsed= {00:00:00.0878196}
// Mesary start
Stopwatch watch = new Stopwatch();
watch.Start();
for (int f = 1; f < 1000000; f++)
{
item.Count = FastInt32.IntParseFast(dt.Rows[i]["TopCount"]);
} // Execute the task to be timed
watch.Stop();
Console.WriteLine("Elapsed: {0}", watch.Elapsed);
Console.WriteLine("In milliseconds: {0}", watch.ElapsedMilliseconds);
Console.WriteLine("In timer ticks: {0}", watch.ElapsedTicks);
// Mesary end
// Mesary start
Stopwatch watch2 = new Stopwatch();
watch2.Start();
for (int n = 1; n < 1000000; n++)
{
item.Count = (int)(dt.Rows[i]["TopCount"]);
} // Execute the task to be timed
watch2.Stop();
Console.WriteLine("Elapsed: {0}", watch2.Elapsed);
Console.WriteLine("In milliseconds: {0}", watch2.ElapsedMilliseconds);
Console.WriteLine("In timer ticks: {0}", watch2.ElapsedTicks);
// Mesary end
¡Más rápido! = ¡Mejor práctica!
Por ejemplo, (int)
es casi seguramente el más rápido porque es un operador en lugar de una llamada a función, pero solo funcionará en ciertas situaciones.
La mejor práctica es utilizar el código más legible que no afecte negativamente a su rendimiento, y 99 de cada 100 veces una conversión entera no está impulsando el rendimiento de su aplicación. Si es así, use la conversión más adecuada y más estrecha que pueda. A veces eso es (int)
. A veces es TryParse()
. A veces es Convert.ToInt32()
.
foreach(DataRow row in someTable.Rows)
{
myInt = (int)row["some int value"];
myInt2 = Int.Parse(row["some int value"]);
myInt2 = Convert.ToInt32(row["some int value"]);
}
Para este ejemplo, si el valor que proviene de la tabla es de hecho un valor int, o un valor de base de datos comparable, entonces usando el
myInt = (int)row["some int value"];
sería el más eficiente, y por lo tanto el más "rápido" porque el
row["some int value"];
será una instancia int de tipo valor encerrada dentro de una instancia de objeto de tipo referencia, por lo que usar el molde de tipo explícito será la más rápida ya que otras personas dijeron que es una operación y no una llamada de función, reduciendo así las operaciones de CPU requeridas. Una llamada a un método de conversión o análisis requeriría operaciones de CPU adicionales y, por lo tanto, no sería tan ''rápido''.