CLR: .Net / Mono / Boo / Otros CLR > C#
Performance
Eternal Idol:
--- Cita de: "JuanK" ---que tan importante es el consumo de memoria a la hora de medir el performance en millones de ciclos?
--- Fin de la cita ---
Puede que en C# incluso mas que en C++ debido a la recoleccion de basura cuantas mas reservas mas comprobaciones ... es por pura logica.
--- Cita de: "JuanK" ---Si tengo una clase X con campos y metodos que tan mas eficiente seria dejar todos sus metodos esticos versus versiones diferentes de los mismos metodos pero no estaticos?
--- Fin de la cita ---
Una comprobacion mirando codigo es lo que deberias hacer.
--- Cita de: "JuanK" ---Es decir reservar 2'500.000 porciones de memoria de tamaño N/x es más rápido que reservar 2'500.000 porciones de memoria de tamaño N? :rolleyes:
--- Fin de la cita ---
Depende de la implementacion ... pero seguro que 2.500.000 de X son mas lentas que 625.000 de X*4 ... menos llamadas menos codigo ejecutado ...
JuanK:
Si eso he visto en las pruebas que he realizado hoy... ahora solo me falta averiguar como demonios hago en C# para reservar un bloque de memoria y asignarlo aun lote de 'punteros' que se encuentran un array <_<
thanks
JuanK:
:o
Haicendo averiguaciones y pruebas , resulta que hacer la misma implementacion usando tipos como clases o estucturas, la instanciacion de 2'500.000 elementos es casi inmediata, como 1/2 segundo mientras que usado generics ( el equivalente a templates en c++, el cual es mi caso) toma casi 5 segundos. :( tal como lo dijo eternal idol se acelera el tiempo de desarrollo pero con un costo de performance adicional.
Estas cifras las obtuve tambien en un foro de Microsoft:
--- Citar ---new int(): 0.006 microseconds
new T() where T is int: 0.030 microseconds
new class(): 0.042 microseconds
new T() where T is class: 2.0 microseconds
--- Fin de la cita ---
Este es el link:
http://forums.microsoft.com/MSDN/ShowPost....SiteID=1&mode=1
No acepto burlas por mi ingles, pues apenas estoy aprendiendo.
Bueno por el momento no se que hacerle , si bien es un tiempo significativo lo puedo considerar como despreciable puesto que esta por demas decir que esta por fuera de mi scope ya que el formato va dirigido a animaciones para videojuego y dificilmente algun cuadro de animacion llegara a ese tamaño de imagen, de hecho ni a la mitas de ese tamaño con el cual hice las pruebas, sin embargo si se me ocurre algo como lo del pool de tipos T pues puede que llegue a implementarlo.
Hablamos. :hola:
JuanK:
:ph34r:
He solucionado el problema de velocidad :) <_<
Pero desde luego no fue precisamente una solucion muy limpia, por el contrario bastante sucia.
Como el problema es por usar generics decidi reducir su uso al maximo en ese metodo porblema, asi que lo que hice fue determinar el tipo T e implementar una solucion especifica para los tipos soportados por mis formatos nativamente (8,16,24,32 bit) y conservar la interfaz generica para los clientes del metodo asi como proveer una solucion generica para los tipos no nativos que se requieran utilizar en un futuro.
Reduje el tiempo de ejecucion a menos de un segundo. :lol:
Codigo anterior:
<!--xc1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td>XCODE </td></tr><tr><td id='XCODE'><!--exc1-->
public T[] ColorArrayDesdeBMP(Bitmap bmp)
{
T[] colorArray = new T[bmp.Height * bmp.Width];
BitmapData bmpd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
IntPtr pbmp = bmpd.Scan0;
byte bytesPorPixel = 0;
int j = 0;
bytesPorPixel = (byte)((int)imagen.informacionBase.ProfundidadColor / 8);
int anchoEnBytes = bmp.Width * bytesPorPixel;
int paddedBytes = ((anchoEnBytes + 3) & ~3) - anchoEnBytes;
int anchoBytesPadd = anchoEnBytes + paddedBytes;
byte[] bmpArr = new byte[bmp.Height * anchoBytesPadd];
System.Runtime.InteropServices.Marshal.Copy(pbmp, bmpArr, 0, bmp.Height * anchoBytesPadd);
bmp.UnlockBits(bmpd);
for (int i = 0; i < bmpArr.Length; i += bytesPorPixel)
{
colorArray[j] = new T();
colorArray[j++].FromBMPColorArray(bmpArr, i);
if (j % bmp.Width == 0)
i += paddedBytes;
}
return colorArray;
}<!--xc2--></td></tr></table><div class='postcolor'><!--exc2-->
Codigo nuevo (cochino pero rapido)
<!--xc1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td>XCODE </td></tr><tr><td id='XCODE'><!--exc1--> public T[] ColorArrayDesdeBMP(Bitmap bmp)
{
BaseColor[] objectArray = new BaseColor[bmp.Height * bmp.Width];
T[] colorArray= new T[1];
Color8[] colorArray8 = new Color8[1];
Color16[] colorArray16 = new Color16[1];
Color24[] colorArray24 = new Color24[1];
Color32[] colorArray32 = new Color32[1];
BitmapData bmpd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
IntPtr pbmp = bmpd.Scan0;
byte bytesPorPixel = (byte)((int)imagen.informacionBase.ProfundidadColor / 8);
int anchoEnBytes = bmp.Width * bytesPorPixel;
int paddedBytes = ((anchoEnBytes + 3) & ~3) - anchoEnBytes;
int anchoBytesPadd = anchoEnBytes + paddedBytes;
byte[] bmpArr = new byte[bmp.Height * anchoBytesPadd];
Type t = typeof(T);
int j = 0;
System.Runtime.InteropServices.Marshal.Copy(pbmp, bmpArr, 0, bmp.Height * anchoBytesPadd);
bmp.UnlockBits(bmpd);
switch (t.Name)
{
case "Color8":
colorArray8 = Array.ConvertAll<BaseColor, Color8>(objectArray, delegate(BaseColor b) { return b as Color8; });
for (int i = 0; i < bmpArr.Length; i += bytesPorPixel)
{
colorArray8[j] = new Color8();
colorArray8[j++].FromBMPColorArray(bmpArr, i);
if (j % bmp.Width == 0)
i += paddedBytes;
}
return colorArray8 as T[];
case "Color16":
colorArray16 = Array.ConvertAll<BaseColor, Color16>(objectArray, delegate(BaseColor b) { return b as Color16; });
for (int i = 0; i < bmpArr.Length; i += bytesPorPixel)
{
colorArray16[j] = new Color16();
colorArray16[j++].FromBMPColorArray(bmpArr, i);
if (j % bmp.Width == 0)
i += paddedBytes;
}
return colorArray16 as T[];
case "Color24":
colorArray24 = Array.ConvertAll<BaseColor, Color24>(objectArray, delegate(BaseColor b) { return b as Color24; });
for (int i = 0; i < bmpArr.Length; i += bytesPorPixel)
{
colorArray24[j] = new Color24();
colorArray24[j++].FromBMPColorArray(bmpArr, i);
if (j % bmp.Width == 0)
i += paddedBytes;
}
return colorArray24 as T[];
case "Color32":
colorArray32 = Array.ConvertAll<BaseColor, Color32>(objectArray, delegate(BaseColor b) { return b as Color32; });
for (int i = 0; i < bmpArr.Length; i += bytesPorPixel)
{
colorArray32[j] = new Color32();
colorArray32[j++].FromBMPColorArray(bmpArr, i);
if (j % bmp.Width == 0)
i += paddedBytes;
}
return colorArray32 as T[];
default:
colorArray = Array.ConvertAll<BaseColor, T>(objectArray, delegate(BaseColor b) { return b as T; });
for (int i = 0; i < bmpArr.Length; i += bytesPorPixel)
{
colorArray[j] = new T();
colorArray[j++].FromBMPColorArray(bmpArr, i);
if (j % bmp.Width == 0)
i += paddedBytes;
}
return colorArray;
}
}<!--xc2--></td></tr></table><div class='postcolor'><!--exc2-->
JuanK:
:lol:
Bie gracias a la ayuda e una persona del foro de Microsoft he llegado a esta solucion, por cierto muy sencilla e ingeniosa, asi obtuve los mismo tiempos que en mi implementacion anterior cambiando una sola linea de la implenentacion original, y bueno adicionando un metodo extra a las clases derivadas de BaseColor
Cree este metodo en la clase base
--- Código: Text ---public abstract BaseColor CreateNew();
y en cada una de las clases que heredan de ella desde luego hubo que implementarlo ej:
--- Código: Text ---class Color8{ ... ... public override BaseColor CreateNew() { return new Color8(); }}
Y finalmente el metodo quedo asi:
<!--xc1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td>XCODE </td></tr><tr><td id='XCODE'><!--exc1-->
/// <summary>Extrae de un BMP sus colores en forma de un array de color compatible de imagen JKI</summary>
/// <param name="bmp">Mapa de bits del cual se estraeran los colores</param>
/// <returns>Array de colores extraidos del Bitmap</returns>
public T[] ColorArrayDesdeBMP(Bitmap bmp)
{
T[] colorArray = new T[bmp.Height * bmp.Width];
BitmapData bmpd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
IntPtr pbmp = bmpd.Scan0;
byte bytesPorPixel = 0;
int j = 0;
T factory = new T();
bytesPorPixel = (byte)((int)imagen.informacionBase.ProfundidadColor / 8);
int anchoEnBytes = bmp.Width * bytesPorPixel;
int paddedBytes = ((anchoEnBytes + 3) & ~3) - anchoEnBytes;
int anchoBytesPadd = anchoEnBytes + paddedBytes;
byte[] bmpArr = new byte[bmp.Height * anchoBytesPadd];
System.Runtime.InteropServices.Marshal.Copy(pbmp, bmpArr, 0, bmp.Height * anchoBytesPadd);
bmp.UnlockBits(bmpd);
for (int i = 0; i < bmpArr.Length; i += bytesPorPixel)
{
colorArray[j] = (T)factory.CreateNew();
colorArray[j++].FromBMPColorArray(bmpArr, i);
if (j % bmp.Width == 0)
i += paddedBytes;
}
return colorArray;
}<!--xc2--></td></tr></table><div class='postcolor'><!--exc2-->
Genial.
Navegación
[*] Página Anterior
Ir a la versión completa