完善主體資料,免費贈送VIP會員!
      * 主體類型
      * 企業名稱
      * 信用代碼
      * 所在行業
      * 企業規模
      * 所在職位
      * 姓名
      * 所在行業
      * 學歷
      * 工作性質
      請先選擇行業
      您還可以選擇以下福利:
      行業福利,領完即止!

      下載app免費領取會員

      NULL

      ad.jpg

      二次開發教程:orm 里使用Emit

      發布于:2019-07-24 16:33:26

      網友投稿

      更多

      比較一下Emit的賦值,反射賦值和直接賦值的效率


      namespace Assignment

      {

          class Program

          {

              static SQLiteConnection conn;

              static string dbStr = "test.db";

              static void Main(string[] args)

              {

                  CreateDB();

                  List<Book> books = new List<Book>();

                  for (int i = 0; i < 1000000; i++)

                  {

                      books.Add(new Book());

                  }

                  Insert(books);

                  Insert(new Book());

       

                  Stopwatch stopwatch = new Stopwatch();

                  stopwatch.Start();

                  var bs = Query<Book>();

                  stopwatch.Stop();

                  Console.WriteLine(stopwatch.ElapsedMilliseconds);

       

                  stopwatch.Restart();

                  var bs1 = QueryEmit<Book>();

                  stopwatch.Stop();

                  Console.WriteLine(stopwatch.ElapsedMilliseconds);

       

                  stopwatch.Restart();

                  var bs2 = Query();

                  stopwatch.Stop();

                  Console.WriteLine(stopwatch.ElapsedMilliseconds);

       

                  Console.ReadLine();

              }

       

              static void CreateDB()

              {

                  SQLiteConnection.CreateFile(dbStr);

                  conn = new SQLiteConnection($"Data Source={dbStr};Version=3;");

                  conn.Open();

       

                  string sql = "create table book (id int,name varchar(20), price double)";

                  SQLiteCommand command = new SQLiteCommand(sql, conn);

                  command.ExecuteNonQuery();

              }

              static void Insert(Book book)

              {

                  string sql = "insert into book values(@id,@name,@price)";

                  SQLiteCommand command = new SQLiteCommand(sql, conn);

                  command.Parameters.AddWithValue("id", book.Id);

                  command.Parameters.AddWithValue("name", book.Name);

                  command.Parameters.AddWithValue("price", book.Price);

       

                  command.ExecuteNonQuery();

              }

              static void Insert(IList<Book> books)

              {

                  string sql = "insert into book values(@id,@name,@price)";

                  var trans = conn.BeginTransaction();

                  SQLiteCommand command = new SQLiteCommand(sql, conn, trans);

                  foreach (var book in books)

                  {

                      command.Parameters.Clear();

                      command.Parameters.AddWithValue("id", book.Id);

                      command.Parameters.AddWithValue("name", book.Name);

                      command.Parameters.AddWithValue("price", book.Price);

       

                      command.ExecuteNonQuery();

                  }

                  trans.Commit();

              }

       

              static List<Book> Query()

              {

                  List<Book> result = new List<Book>();

                  string sql = "select * from book";

                  SQLiteCommand command = new SQLiteCommand(sql, conn);

                  var reader = command.ExecuteReader();

                  while (reader.Read())

                  {

                      Book book = new Book();

                      book.Id = (int)reader.GetValue(0);

                      book.Name = (string)reader.GetValue(1);

                      book.Price = (double)reader.GetValue(2);

                      result.Add(book);

                  }

                  return result;

              }

       

              static List<T> Query<T>()

              {

                  List<T> result = new List<T>();

                  string sql = "select * from book";

                  SQLiteCommand command = new SQLiteCommand(sql, conn);

                  Type type = typeof(T);

                  var reader = command.ExecuteReader();

                  var readerMap = new ReaderMap(reader);

                  var propertyMap = new PropertyMap(readerMap, type);

                  while (reader.Read())

                  {

                      T r = (T)Activator.CreateInstance(type);

                      int len = reader.FieldCount;

                      for(int i = 0; i < len; i++)

                      {

                          propertyMap[i].SetValue(r, reader.GetValue(i));

                      }

                      result.Add(r);

                  }

       

                  return result;

              }

              

              static List<T> QueryEmit<T>()

              {

                  Type type = typeof(T);

       

                  List<T> result = new List<T>();

                  string sql = "select * from book";

                  SQLiteCommand command = new SQLiteCommand(sql, conn);

                  var reader = command.ExecuteReader();

                  var readerMap = new ReaderMap(reader);

                  var propertyMap = new PropertyMap(readerMap, type);

       

                  var func = GetSetter<T>(reader, propertyMap);

       

                  while (reader.Read())

                  {

                      T r = (T)func(reader);

                      result.Add(r);

                  }

       

                  return result;

              }

       

              static Func<SQLiteDataReader, object> GetSetter<T>(SQLiteDataReader reader, PropertyMap map)

              {

                  Type bookType = typeof(T);

                  var constructor = bookType.GetConstructors().FirstOrDefault();

                  DynamicMethod setter = new DynamicMethod("setbook", bookType, new Type[] { typeof(SQLiteDataReader) });

                  setter.DefineParameter(0, ParameterAttributes.In, "reader");

       

                  var iLGenerator = setter.GetILGenerator();

       

                  iLGenerator.DeclareLocal(bookType); //Ldloc_0 book

                  iLGenerator.DeclareLocal(typeof(object));//Ldloc_1 reader.GetValue

       

                  iLGenerator.Emit(OpCodes.Nop);

                  iLGenerator.Emit(OpCodes.Newobj, constructor);

                  iLGenerator.Emit(OpCodes.Stloc_0);

                  iLGenerator.Emit(OpCodes.Nop);

       

                  var getM = typeof(DbDataReader).GetMethod("GetValue");

       

                  int len = map.Count;

                  for (int i = 0; i < len; i++)

                  {

                      ///讀數據

                      iLGenerator.Emit(OpCodes.Ldarg_0);

                      iLGenerator.Emit(OpCodes.Ldc_I4, i);

                      iLGenerator.Emit(OpCodes.Callvirt, getM);

                      iLGenerator.Emit(OpCodes.Stloc_1);

                      iLGenerator.Emit(OpCodes.Nop);

       

                      var tp = map[i];

                      iLGenerator.Emit(OpCodes.Ldloc_0);

                      iLGenerator.Emit(OpCodes.Ldloc_1);

                      if (tp.PropertyType.IsValueType)

                          iLGenerator.Emit(OpCodes.Unbox_Any, tp.PropertyType);

                      else

                          iLGenerator.Emit(OpCodes.Castclass, tp.PropertyType);

       

                      var mt = tp.GetSetMethod();

       

                      iLGenerator.Emit(OpCodes.Callvirt, mt);

                      iLGenerator.Emit(OpCodes.Nop);

                  }

       

                  iLGenerator.Emit(OpCodes.Ldloc_0);

                  iLGenerator.Emit(OpCodes.Ret);

       

                  return (Func<SQLiteDataReader, object>)setter.CreateDelegate(typeof(Func<SQLiteDataReader,object>));

              }

       

              static Book QueryBook(SQLiteDataReader reader)

              {

                  Book book = new Book();

                  book.Id = (int)reader.GetValue(0);

                  book.Name = (string)reader.GetValue(1);

                  book.Price = (double)reader.GetValue(2);

                  return book;

              }

          }

          public class PropertyMap

          {

              private PropertyInfo[] properties = null;

              public PropertyMap(ReaderMap readerMap,Type type)

              {

                  int len = readerMap.Count;

                  Count = len;

                  var ps = type.GetProperties();

                  properties = new PropertyInfo[len];

                  for(int i = 0; i < len; i++)

                  {

                      var readerItem = readerMap[i];

                      var tp = ps.FirstOrDefault(p => p.Name.ToUpper() == readerItem.Name.ToUpper());

                      if (tp != null)

                      {

                          if (tp.PropertyType.IsAssignableFrom(readerItem.Type))

                          {

                              properties[i] = tp;

                          }

                      }                

                  }

              }

              public PropertyInfo this[int i]

              {

                  get

                  {

                      return properties[i];

                  }

              }

              public int Count { get; private set; }

          }

          public class ReaderMap

          {

              private ReaderItem[] items = null; 

              public ReaderMap(SQLiteDataReader reader)

              {

                  int len = reader.FieldCount;

                  Count = len;

                  items = new ReaderItem[len];

                  for(int i = 0; i < len; i++)

                  {

                      items[i] = new ReaderItem

                      {

                          Id = i,

                          Name = reader.GetName(i),

                          Type = reader.GetFieldType(i)

                      };

                  }

              }

              public int Count

              {

                  get;

                  private set;

              }

              public ReaderItem this[int i]

              {

                  get

                  {

                      return items[i];

                  }

              }

          }

          public class ReaderItem

          {

              public int Id { get; set; }

              public string Name { get; set; }

              public Type Type { get; set; }

          }

          public class Book

          {

              public int Id { get; set; }

              public string Name { get; set; }

              public double Price { get; set; }

              public Book()

              {

                  Id = 0;

                  Name = "Name";

                  Price = 11.9;

              }

       

              public override string ToString()

              {

                  return $"Id; {Id}\tName: {Name}\tPrice: {Price}";

              }

          }

      }

      輸出結果為


      反射時間2725


      Emit 時間1745


      直接賦值1604

      本文版權歸腿腿教學網及原創作者所有,未經授權,謝絕轉載。

      未標題-1.jpg

      上一篇:二次開發教程:Dapper里使用Attribute自定義映射關系

      下一篇:二次開發教程:Emit 循環

      主站蜘蛛池模板: 精品视频午夜一区二区| 精品一区二区三区无码视频| 亚洲综合在线一区二区三区| 国产无套精品一区二区| 怡红院一区二区在线观看| 国产精品视频第一区二区三区| 国产一区二区精品久久岳√| 中文字幕人妻AV一区二区| 亚洲一区二区三区四区在线观看| 国产av一区二区精品久久凹凸| 日韩一区二区在线视频| 无码少妇一区二区性色AV| 在线观看国产一区| 狠狠色婷婷久久一区二区三区| 老湿机一区午夜精品免费福利| 国产一区二区在线| 无码aⅴ精品一区二区三区| 99精品国产高清一区二区麻豆 | 日韩精品无码中文字幕一区二区| 精品国产毛片一区二区无码| 亚洲国产精品成人一区| 日韩视频在线观看一区二区| 国产伦精品一区二区三区无广告| 无码国产精品久久一区免费| 亚洲AV日韩综合一区| 国产激情一区二区三区小说 | 少妇无码一区二区三区免费| 中文字幕一区二区日产乱码| 中文字幕在线无码一区二区三区 | 精品国产AV一区二区三区| 人妻激情偷乱视频一区二区三区 | 无码人妻精品一区二区蜜桃网站 | 在线电影一区二区三区| 日韩伦理一区二区| 日韩毛片一区视频免费| 国产一区二区三区不卡AV| 亚洲电影一区二区三区| 亚洲a∨无码一区二区| 福利片免费一区二区三区| AV怡红院一区二区三区| 亚洲AV色香蕉一区二区|