Los secretos del casting al descubierto

Visto lo animada que estuvo la discusión en el anterior post sobre los diferentes casts en C#, no podía dejar pasar la oportunidad de explicar un poco en que consistía el acertijo. Como algunos comentabais en los comentarios, las dos operaciones, as y cast explicito, son distintas en funcionalidad y también internamente. Vamos a ver por qué:

concursante = (Concursante)o;

En esa línea, intentaremos convertir el objeto o a Concursante. Si podemos, devolveremos un objeto de tipo concursante, si no podemos lanzaremos una excepción.

concursante = o as Concursante;

En esta otra línea, comprobaremos primero si el objeto es convertible a Concursante. Si lo es, lo convertiremos y devolveremos, si no lo es devolveremos null. Internamente, el operador as se convierte en una instrucción de tipo isinst, mientras que el cast directo se convierte en una instrucción castclass. Pero dejémonos de teoría y vamos a lo que nos interesa. Con un sencillo programa podemos comprobar cual de los dos es más rápido. Por ejemplo, así:

Concursante concursante = null;
object o = new Concursante();

ArrayList array = new ArrayList();

Stopwatch watch = new Stopwatch();
Console.WriteLine("Begin casting");

for (int i = 0; i < 100; i++)
{
    watch.Start();

    for (int j = 0; j < 10000000; j++)
    {
        concursante = (Concursante)o;
        concursante.Nombre = "Rosa";
    }

    watch.Stop();

    array.Add(watch.ElapsedMilliseconds);
    watch.Reset();
}

float ms = 0;

for (int i = 0; i < array.Count; i++)
{
    ms += float.Parse(array[i].ToString());
}

ms = ms / array.Count;

Console.WriteLine("Median elapsed time: {0} ms", ms);

Si, el programa tiene un poco mas de miga, pero tiene su sentido. Hemos de recordar que un casting, de una forma u otra, es una operación con un coste muy, muy pequeño por si sola. Para poder medirla con un poco de precisión, realizaremos diez millones de casting cien veces, y calcularemos la media. Ejecutado en mi portátil mientras escribo esto, el resultado es de unos cuantos milisegundos (40, 50…) en cada uno de los casos. Recordemos que estamos hablando del tiempo de ejecución de 10.000.000 operaciones. Lo curioso es que al ejecutar el mismo código en modo release o en modo debug, con o sin optimizaciones, nos dará resultados distintos. Qué es lo que esta pasando?

Esa será la respuesta que dejaré sin responder, por una sencilla razón. Mi compañero Luis Guerrero me ha prometido realizar un interesantísimo post sobre este mismo tema, metiéndose hasta el fondo del asunto con WinDBG. Así pues, le paso el testigo 😉


Rock Tip. Ya he nombrado por aquí a los finlandeses Turisas, pero es justo que después de verles la semana pasada en directo por segunda vez, vuelva a recordarlos. Con vosotros, Battle Metal. Enjoy!!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *