private void ReadType(System.Type type) { const Ref::BindingFlags BF = Ref::BindingFlags.Static | Ref::BindingFlags.Public | Ref::BindingFlags.NonPublic; afh.Application.Log log = Program.log; log.WriteLine("ReadType: {0}", type.FullName); foreach (Ref::MethodInfo minfo in type.GetMethods(BF)) { // 超いい加減引数チェック if (TestMethod.IsTestable(minfo)) { TestMethod test = new TestMethod(minfo); test.WriteSummary(log); this.listBox1.Items.Add(test); } BenchMethodAttribute benchattr = BenchMethod.GetAttribute(minfo, log); if (benchattr != null) { BenchMethod bench = new BenchMethod(minfo, benchattr); this.listBox1.Items.Add(bench); } } }
//=========================================================== // 初期化 //=========================================================== public static BenchMethodAttribute GetAttribute(Ref::MethodInfo minfo, afh.Application.Log log) { object[] attrs = minfo.GetCustomAttributes(typeof(BenchMethodAttribute), false); if (attrs.Length == 0) { return(null); } BenchMethodAttribute attr = (BenchMethodAttribute)attrs[0]; if (!minfo.IsStatic) { log.WriteLine("メソッド '{0}' は static でない為 Benchmark を実行出来ません。", minfo); return(null); } if (minfo.GetParameters().Length != 0) { log.WriteLine("メソッド '{0}' の呼び出しには引数が必要なので Benchmark を実行出来ません。", minfo); return(null); } return(attr); }
public BenchMethod(Ref::MethodInfo minfo, BenchMethodAttribute attr) { this.minfo = minfo; this.attr = attr; Emit::DynamicMethod m = new Emit::DynamicMethod( "bench", typeof(TimeSpan), new System.Type[] { typeof(int) }, minfo.DeclaringType ); // // 宣言 // Emit::ILGenerator ilgen = m.GetILGenerator(); System.Type type_dt = typeof(System.DateTime); Emit::LocalBuilder loc_start = ilgen.DeclareLocal(type_dt); Emit::LocalBuilder loc_end = ilgen.DeclareLocal(type_dt); Emit::LocalBuilder loc_i = ilgen.DeclareLocal(typeof(int)); Ref::MethodInfo m_get_Now = type_dt.GetMethod("get_Now"); Ref::MethodInfo m_op_Subtraction = type_dt.GetMethod("op_Subtraction", new System.Type[] { type_dt, type_dt }); Emit::Label label_loopC = ilgen.DefineLabel(); Emit::Label label_loopJ = ilgen.DefineLabel(); // // ロジック // //-- pro ilgen.Emit(Emit::OpCodes.Call, m_get_Now); ilgen.Emit(Emit::OpCodes.Stloc, loc_start); //-- loop ilgen.Emit(Emit::OpCodes.Ldc_I4_0); ilgen.Emit(Emit::OpCodes.Dup); // ilgen.Emit(Emit::OpCodes.Stloc, loc_i); ilgen.Emit(Emit::OpCodes.Br_S, label_loopJ); ilgen.MarkLabel(label_loopC); ilgen.Emit(Emit::OpCodes.Call, minfo); if (minfo.ReturnType != typeof(void)) { ilgen.Emit(Emit::OpCodes.Pop); } ilgen.Emit(Emit::OpCodes.Ldloc, loc_i); ilgen.Emit(Emit::OpCodes.Ldc_I4_1); ilgen.Emit(Emit::OpCodes.Add); ilgen.Emit(Emit::OpCodes.Dup); // ilgen.Emit(Emit::OpCodes.Stloc, loc_i); ilgen.MarkLabel(label_loopJ); //ilgen.Emit(Emit::OpCodes.Ldloc,loc_i); ilgen.Emit(Emit::OpCodes.Ldarg_0); ilgen.Emit(Emit::OpCodes.Blt_S, label_loopC); //-- epi ilgen.Emit(Emit::OpCodes.Call, m_get_Now); ilgen.Emit(Emit::OpCodes.Stloc, loc_end); ilgen.Emit(Emit::OpCodes.Ldloc, loc_end); ilgen.Emit(Emit::OpCodes.Ldloc, loc_start); ilgen.Emit(Emit::OpCodes.Call, m_op_Subtraction); ilgen.Emit(Emit::OpCodes.Ret); this.meth = (MeasureTime)m.CreateDelegate(typeof(MeasureTime)); }