Showing posts with label Code. Show all posts
Showing posts with label Code. Show all posts

Thursday, January 11, 2007

Improving FileHelpers Performance with Reflection Emit

I´m in the works for the version 2.0 of the library and one of the milestones is to improve a bit the performance (mostly the use of reflection and string handling)

Now I´m trying to use the cool DynamicMethods of .NET 2.0 and I´m surprised how easy and fast them are !!

I just finish to implement the setters via a Dynamic Method using the CreateDelegate and I get a 25% of improved performance over the past versions !!!! (in files with more than 500 or 1000 records)

Here is the code that I´m using:

For example in the FieldBase I was using the FieldInfo.SetValue but now I create a new method at run time

(Suppose that the RecordClass is SampleType and the field Field1 of DateTime)

static void SetField1(object record, object val)

{

((SampleType)record).Field1 = (DateTime)val;

}

I need so a Delegate for these methods calls (all private to the FieldBase class)

delegate void SetValueDelegate(object record, object value);

SetValueDelegate mSetDelegate;

finally playing a bit with Reflector we need to add to the constructor we need these lines:

protected FieldBase(FieldInfo fi)

{

DynamicMethod dm = new DynamicMethod("__SetFH__" + fi.Name, typeof(void),

new Type[] { typeof(object), typeof(object) }, fi.DeclaringType, true);

ILGenerator il = dm.GetILGenerator();

il.Emit(OpCodes.Ldarg_0);

il.Emit(OpCodes.Castclass, fi.DeclaringType);

il.Emit(OpCodes.Ldarg_1);

if (fi.FieldType.IsValueType)

il.Emit(OpCodes.Unbox_Any, fi.FieldType);

else

il.Emit(OpCodes.Castclass, fi.FieldType);

il.Emit(OpCodes.Stfld, fi);

il.Emit(OpCodes.Ret);

mSetDelegate = (SetValueDelegate)dm.CreateDelegate(typeof(SetValueDelegate));

And at last instead of using the slow:

mFieldInfo.SetValue(record, val);

We use :

mSetDelegate(record, val);

I will post the benchmarks when I finish the tweaks.

See ya

Sunday, December 17, 2006

A useful Image Converter for the library

Some user ask for a way to read/write images with the library.

So I create this converter that you can copy and paste in your code:

public sealed class ImageConverter: ConverterBase
{
public override object StringToField(string from)
{
Byte[] bitmapData;
bitmapData = Convert.FromBase64String(from);
System.IO.MemoryStream streamBitmap = new System.IO.MemoryStream(bitmapData);
return Image.FromStream(streamBitmap);
}

public override string FieldToString(object from)
{
Image ima = (Image) from;
System.IO.MemoryStream ms = new System.IO.MemoryStream();
ima.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return Convert.ToBase64String(ms.ToArray());
}
}

Note: you can of course change the ImageFormat to whatever you want, I use PNG because is lost less and compress the resulting strings =)

To use this converter you need some code like:

[FieldConverter(typeof(ImageConverter))]
public Image MyImage;

Easy isn't ?

Happy Coding !!