Set Value on Array: Performance Test


//
// Please refer to http://blogs.msdn.com/haibo_luo "Late-bound array operations" post
//
// To compile this file, you need download Vance's CodeTimers class
// @ http://blogs.msdn.com/vancem/archive/2006/09/21/765648.aspx
//
// THIS CODE IS PROVIDED "AS IS", WITH NO WARRANTIES INTENDED OR IMPLIED. USE AT YOUR OWN RISK
//

using System;
using System.Collections.Generic;
using System.Text;
using PerformanceMeasurement;
using System.Reflection.Emit;
using System.Reflection;

namespace ArraySetValuePerfMeasurement {
delegate void MySetValue(Array array, int index, int value);

class Program {
static void Main(string[] args) {
// Measure how long it takes to fetch all the keys exactly once
MultiSampleCodeTimer timer = new MultiSampleCodeTimer(8, 1000000);
Console.WriteLine("Data units of msec resolution = " + MultiSampleCodeTimer.ResolutionUsec.ToString("f6") + " usec");

Array x = Array.CreateInstance(typeof(int), 10);

// early-bind set
int[] y = (int[])x;

timer.Measure("Early-bound assignment ", delegate {
y[0] = 100;
y[1] = 200;
y[2] = 300;
y[3] = 400;
y[4] = 500;
y[5] = 600;
y[6] = 700;
y[7] = 800;
y[8] = 900;
y[9] = 1000;
});

timer.Measure("Late-bound set via Array.SetValue ", delegate {
x.SetValue(100, 0);
x.SetValue(200, 1);
x.SetValue(300, 2);
x.SetValue(400, 3);
x.SetValue(500, 4);
x.SetValue(600, 5);
x.SetValue(700, 6);
x.SetValue(800, 7);
x.SetValue(900, 8);
x.SetValue(1000, 9);
});

DynamicMethod dm = new DynamicMethod("SetValueByStelem", typeof(void),
new Type[] { typeof(Array), typeof(int), typeof(int) }, typeof(Program));
ILGenerator ilgen = dm.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Castclass, x.GetType());
ilgen.Emit(OpCodes.Ldarg_1); // index
ilgen.Emit(OpCodes.Ldarg_2); // value
ilgen.Emit(OpCodes.Stelem_I4);
ilgen.Emit(OpCodes.Ret);
MySetValue sv = (MySetValue)dm.CreateDelegate(typeof(MySetValue));

timer.Measure("Late-bound set via DynamicMethod/Stelem ", delegate {
sv(x, 0, 100);
sv(x, 1, 200);
sv(x, 2, 300);
sv(x, 3, 400);
sv(x, 4, 500);
sv(x, 5, 600);
sv(x, 6, 700);
sv(x, 7, 800);
sv(x, 8, 900);
sv(x, 9, 1000);
});

MethodInfo mi = x.GetType().GetMethod("Set");
timer.Measure("Late-bound set via Set MethodInfo.Invoke", delegate {
mi.Invoke(x, new object[] { 0, 100 });
mi.Invoke(x, new object[] { 1, 200 });
mi.Invoke(x, new object[] { 2, 300 });
mi.Invoke(x, new object[] { 3, 400 });
mi.Invoke(x, new object[] { 4, 500 });
mi.Invoke(x, new object[] { 5, 600 });
mi.Invoke(x, new object[] { 6, 700 });
mi.Invoke(x, new object[] { 7, 800 });
mi.Invoke(x, new object[] { 8, 900 });
mi.Invoke(x, new object[] { 9, 1000 });
});

dm = new DynamicMethod("SetValueBySet", typeof(void),
new Type[] { typeof(Array), typeof(int), typeof(int) }, typeof(Program));

ilgen = dm.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Castclass, x.GetType());
ilgen.Emit(OpCodes.Ldarg_1);
ilgen.Emit(OpCodes.Ldarg_2);
ilgen.Emit(OpCodes.Call, mi);
ilgen.Emit(OpCodes.Ret);

sv = (MySetValue)dm.CreateDelegate(typeof(MySetValue));

timer.Measure("Late-bound set via DynamicMethod/Set ", delegate {
sv(x, 0, 100);
sv(x, 1, 200);
sv(x, 2, 300);
sv(x, 3, 400);
sv(x, 4, 500);
sv(x, 5, 600);
sv(x, 6, 700);
sv(x, 7, 800);
sv(x, 8, 900);
sv(x, 9, 1000);
});
}
}
}

Comments (1)
  1. The type " System.Array " provides us a set of API for the late-bound array operations, including array

Comments are closed.

Skip to main content