By the way

english — Tags: , — @ 20:58

Thank you Cecy! 140+ tracks of pure nice music.

Notas de desempeño

english — Tags: , — @ 22:30

A pesar de todos los comentarios puristas, usualmente absurdos y sin fundamentos, referentes a la plataforma Mono (y MS .NET), escribir código en esa plataforma realmente agiliza el desarrollo, en .NET no todo es “arrastrar y soltar”, ni llenar las “formas” y cambiarles los colores arbitrariamente, ni hacer supuesta orientación a objetos copiando trozos de código (estáticos por cierto) a diferentes métodos. Escribir código en .NET cualquiera lo puede hacer, pero el hacerlo bien requiere habilidades y experiencia en otros lenguajes.

Podríamos pensar para escribir una aplicación de tiempo real debemos seleccionar un lenguaje que pueda al final general un binario dependiente de plataforma y arquitectura, de esta forma se podrán explotar, entre otras cosas, las capacidades de CPU y un manejo adecuado de memoria y administración de esta, ¿Qué es lo malo?, hay que saber como hacerlo y aprender lleva tiempo y tiempo es dinero, más tiempo significa más inversión y eso es algo de lo que usualmente no disponemos, además la plataforma que se ofrece a través de la conjunción del CLR y el CIL hacen que podamos tener lo mejor de los dos mundos, hacer que el tiempo de desarrollo se reduzca y el desempeño sea al menos semejante a una aplicación de arquitectura y plataforma dependiente, es obvio que un desempeño excelente en comparación a un compilado-dependiente no se podrá obtener, pero sin embargo siempre se busca el mejor.

Mi proyecto actual del trabajo es el claro ejemplo del extremo, donde se debe escribir una aplicación en .NET con un desempeño excelente, el retardo máximo de actualización es de 3 segundos, actualmente lo he bajado de 6-8 a 3-1 segundos, cosa que me agrada, pero seguro se puede mejorar más, algunas cosas que me ayudaron a mejorar el desempeño fue:

  1. Parar el uso de Enumeradores, reemplazalos con punteros, con código no administrado.
  2. No usar indexadores para acceder a arreglos cambiando el código a un uso de aritmética de punteros, con código no administrado.
  3. Concatenaciones a travéz de System.Text.StringBuilder, en vez de utilizar el clásico “cadena + cadena“.
  4. Débido a que recibo información binaria de estructuras escritas en C mediante un broadcast, es necesario generar las versiones C# correspondientes a aquellas struct en C con un Marshalling de modo que se pueda hacer un casting de tipo *(Estructura *) ptr.

Existe un artículo que muestra un buen caso de ejemplo indicando desempeño al momento de hacer ciclos a arreglos, dentro se utiliza un ejemplo de punteros escritos en C++ administrado, la versión de C# sería algo así:

using System;

namespace Iterations
{
public class Pointer
{
public unsafe static void iterate (Data data)
{
double d;
fixed (double *ptr = &data.Array [0]) {
int l = data.Array.Length;
for (int i = 0; i < l; i++)
d = *(ptr +i);
}
}
}
}

Los resultados son contundentes:

repetitions: 1000
iterations: 1.000000e+006

Enumeration: 32.87 seconds
Indexing: 11.246 seconds
Indirect Arrays: 10.172 seconds
Direct Arrays: 5.44 seconds
Pointer Math: 4.828 seconds

El retardo principal se debe a los objetos generados durante la enumeración, foreach no es la elección en aplicaciones de alto desempeño, sin duda es sencillo de implementar pero es lento al ejecutar, la solución más rápida a travéz de punteros se debe a que validaciones como el índice del arreglo no es considerado, dejando todo la lógica de validación al programador.

Hay cosas que me faltan de eliminar como ese abuso exagerado de boxing/unboxing al momento de tener mi colección de estructuras recibidas por el broadcast, además de la creación innecesario de tipos por valor, reemplazando con una lista enlazada en código no administrado y pasos por referencia respectivamente. Un ejemplo de esto sería:

using System;

namespace Research
{
unsafe public struct MyStruct
{
public MyStruct (int integer)
{
Integer = integer;
Next = null;
}

public int Integer;
public MyStruct *Next;

public override string ToString ()
{
return "Integer: "+Integer+" at "+
"Ptr "+((int)&(*Next));
}
}

//Quick sample, don't bother me ;-)
public class Sample
{
unsafe public static void Main (string []args)
{
MyStruct obj1 = new MyStruct ();
MyStruct obj2 = new MyStruct ();
obj1.Next = null;
obj2.Next = &obj1;
obj1.Integer = 1;
obj2.Integer = 2;
ChangeByPointer (&obj1.Integer);
ChangeByReference (ref obj2.Integer);
Console.WriteLine (obj1 +" * "+ obj2);
}

unsafe public static void ChangeByPointer (int *reference)
{
*(reference) += 5;
}

unsafe public static void ChangeByReference (ref int reference)
{
reference += 5;
}
}
}

Algo interesante es el hecho de que ambos métodos generan la misma secuencia de instrucciones CIL, lo cual obviamente indica que son iguales, por tal razón cualquier elección es buena:

//... more before

// method line 5
.method public static hidebysig
default void ChangeByPointer (int32* reference) cil managed
{
// Method begins at RVA 0x21c4
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: dup
IL_0002: ldind.i4
IL_0003: ldc.i4.5
IL_0004: add
IL_0005: stind.i4
IL_0006: ret
} // end of method Sample::default void ChangeByPointer (int32* reference)

// method line 6
.method public static hidebysig
default void ChangeByReference (int32& reference) cil managed
{
// Method begins at RVA 0x21cc
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: dup
IL_0002: ldind.i4
IL_0003: ldc.i4.5
IL_0004: add
IL_0005: stind.i4
IL_0006: ret
} // end of method Sample::default void ChangeByReference (int32& reference)
//more later...

Faltan detalles por mejorar, pero sin duda “jugar” con punteros siempre será lo mejor.

Yesterday-Today

english — Tags: , , — @ 17:19

A friend of mine, Carlos, visited me yesterday, we went to hang somewhere around to talk, to remember old times and to have fun, this happened until 04:00AM, quite nice.

He’s doing some apps using newest MS’s technology, showed me an application to write arbitrary-widgets based on its drawing called Expression using XAML mainly used in MS Windows Vista with its WinFX, Avalon and so on, that XML-defined extension remembered something in our side.

BTW, while searching some english written phrases, I noticed a page that includes severals phrases and their “definition”, very usefull for me, a non-native english speaker, and learning some never hurts.

We are not drunk

OnceUponATime ();

english — Tags: , — @ 03:27


public sealed class Mario
{
public static int OnceUponATime ()
{
return 23;
}
}

Hours later

english — Tags: , — @ 22:51

And yes.. some hours later, some debs downloaded.. GNOME 2.14!! Now I have a mix of GNOME 2.14 and 2.12, but runs quite good, faster and I just love it! :)

Today two things happened, first I noticed that we will use dbus for IPC, great news! second, 6 seconds delays is too much, need to increase performance in my current development less delay is better.

GNOME 2.14

BTW, Using testing/unstable is quite risky but I like living in the edge, however even I’m running testing/unstable the ndiswrapper packages for current kernel aren’t packaged, yet, at least officially, so if you are using a ndiswrapper-enabled wireless card, you need to add:

deb http://puga.vdu.lt/debian sarge main
deb-src http://puga.vdu.lt/debian sarge main
deb http://puga.vdu.lt/debian sid main
deb-src http://puga.vdu.lt/debian sid main

to your sources.lists, works for me. Don’t forget:

# apt-get install wireless-tools

Update: ndiswrapper stills crashes, if you enable it using /etc/modules crashes kernel, sometimes works some others crashes keyboard… so.. still unstable, will wait for next ndiswrapper relase.

Debian

english — Tags: , — @ 23:56

At work we have choosed Debian as main GNU/Linux distribution.

I’m very very happy!! :-D I even installed Debian (like old times) in my laptop!, I feel weird using an older GNOME release.

Debian 3.1

Bugzilla

english — Tags: , — @ 21:07

Forge Novell have enabled Bugzilla support for hosted projects, now MonoUML has its bugzilla!, see the wiki too ;-)

MonoCanvas, closer.

english — Tags: , , — @ 15:24

The updating to the Gtk# based version is closest ever, I’m missing Copy&Paste, DnD and MonoCanvas.Line, no doubt Line’s implementation will take some time due to behavioral details when line is “glued” to other elements, after finishing it first release will hit the streets. While implementing this API I’ve been testing performance against its older brother, and yes, works better and faster, I was worried about this last solution wouldn’t choose any other if this fails! :-P . I feel exaggerating is good to test your application in the worst case scenario, some kind of extremist but doing it that way feels better.

Subclassing Shapes in MonoCanvas is easy, you need to implement the InnerElement, usually the drawn element, and subclass from ShapeGroup. The following is a sample that would be Actor class, spplited in ActorElement.cs:

using System;
using Drawing = System.Drawing;
using MonoCanvas;

namespace MonoCanvasGtkSharp
{

public class ActorElement : Element
{

public ActorElement () : base ()
{ }

public override void Draw (Drawing.Graphics graphics)

{
Drawing.Rectangle r = base.Rectangle;
int headWidth = r.Width / 3;
int headHeight = r.Height / 4;

Drawing.Rectangle head = new Drawing.Rectangle (
headWidth, 0,
headWidth, headHeight);
graphics.FillEllipse (base.Brush, head);

graphics.DrawEllipse (base.Pen, head);

int half = r.Width / 2;
graphics.DrawLine (base.Pen, half,
headHeight, half / 2, headHeight * 2);
graphics.DrawLine (base.Pen, half,
headHeight, r.Width - half / 2, headHeight * 2);

graphics.DrawLine (base.Pen, half,
headHeight, half, headHeight * 3);

graphics.DrawLine (base.Pen, half,
headHeight * 3, half / 2, r.Height);
graphics.DrawLine (base.Pen, half,
headHeight * 3, r.Width - half / 2, r.Height);

}
}

}

And ActorShape.cs:

using Gtk;
using Gdk;
using System;
using MonoCanvas;

namespace MonoCanvasGtkSharp
{

public class ActorShape : ShapeGroup
{

public ActorShape () : base ()
{
base.InnerElement = new ActorElement ();
base.AddShape (new TextShape ("Actor name",
base.X, base.Y + base.Height,
100, 20), true);
}
}

}

Notice the following, ActorElement class only draws the Actor but might be doing other things, the second parameter of ShapeGroup.AddShape, determines Shape’s independece, meaning that the Shape is allowed to act as an Independent Shape (Moved and Resizing be dragging). This is a quick sample for subclassing MonoCanvas, the idea is to be easy and rapid to implement to create UMLCanvas.

MonoCanvas' actor  MonoCanvas' actor

Días libres

Uncategorized — Tags: , — @ 23:25

Ahora, desde el lunes, estoy en otra área de la planta y a pesar del cambio de clima que siento durante y después de llegar al departamento donde estoy, me gusta, hago cosas que disfruto y el lugar esta aislado, usualmente estamos en silencio y es posible trabajar y lo mejor, el día se me va como el agua, además tengo algunos planes para poder ser más útil :-) , solo espero que se tome una decisión de OS y todo será felicidad.

Como extraño mis días de vacaciones, pero bueno 3 días son buenos.

Por cierto, que el Ezine de Mono Hispano ya tiene 3 articulos listos y yo tengo tantas ideas para otros más.

Back again

english — Tags: , — @ 18:01

What’s new? Some phone… that’s all.

Tomorrow will start my move due to my new project. Pure C, pure GNU, pure Linux, pure bliss.

Next Page »
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2004-2010 Mario Carrion | powered by WordPress with Barecity