rss resume / curriculum vitae linkedin linkedin gitlab github twitter mastodon instagram
Notas de desempeí±o, 2
May 01, 2006

Despuí©s de haber hecho lo antes comentado y cambiar las clases por estructuras he notado que (sin la menor duda) se acelara el desempeí±o, he bajado la respuesta de 6~8 segundos a menos de un segundo, lo cual es algo grandioso, procesar mí¡s de 21000 estructuras de aproxidamente 1500 bytes cada una es fantí¡stico, el consumo de CPU es de 1%-3% (hablando de un P4 2.4Ghz), claro que este caso de prueba es "el peor de los casos" y tambií©n, aíºn, hay detalles que podrí­an ser mejorados, los resultados son excelentes. Durante la recepcií³n utilizo la solucií³n del marshalling+cast, de modo que se hace un cast explí­cito al tipo de estructura, por ejemplo, suponiendo que tenemos una estructura definida como:

[StructLayout (LayoutKind.Explicit)]
public struct MyStruct
{
[FieldOffset (0)]
public int Integer;

[FieldOffset (4)]
public short Short;
}

Podrí­amos dentro de alguna parte de nuestra lí³gica de procesamiento del flujo binario, hacer el cast:

fixed (byte *data = reader.ReadBytes (sizeof (MyStruct))) {
header = *(MyStruct *) data;
}

Donde el flujo lo leemos a traví©s de la variable reader (BinaryReader). Lo mí¡s probable es que este proceso se encuentre dentro de un ciclo infinito que se encuentra recibiendo la informacií³n del flujo de red. Despuí©s de unas pruebas, que hice por simple curiosidad, note algo muy interesante de las formas de obtener el tamaí±o de una definicií³n de estructura y clase, lo mí¡s sorprendente fue que el mí©todo propuesto por "Marshal.SizeOf (typeof (MyStruct))", es mí¡s lento, y sin duda es cierto, pues cada ocasií³n que es llamado se realiza un asignacií³n por la CLR para calcular su tamaí±o.

repetitions: 1000
iterations: 1.000000e+006

TestSizeOfStatic : 7.773 seconds TestSizeOf: 2.781 seconds TestSizeOfMarshal : 50.093 seconds

Debido a que sizeof íºnicamente sirve para tipos por valor, no es posible aplicar este mí©todo a una clase y tendrí­amos que utilizar Marshal.SizeOf para obtener este tamaí±o, una solucií³n para no afectar el desempeí±o y no utilizar siempre la opcií³n no recomendada es agregando una propiedad estí¡tica a nuestra clase ademí¡s de una variable privada estí¡tica que mantenga este tamaí±o, algo como:

[StructLayout (LayoutKind.Sequential)]
public class MyClass
{
public int Integer;
public short Short;

static unsafe MyClass ()
{
_size = Marshal.SizeOf (typeof (MyClass));
}

public static int Size
{
get { return _size; }
}

private static int _size;
}

Ademí¡s hay que recordar que el overhead de utilizar una clase en comparacií³n a una estructura es mayor. Hay detalles en las clases, al igual que en las estructuras, que deben ser consideradas, el sitio de mono tiene algunos buenos consejos para esto.


Back to posts