完善主體資料,免費贈送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 循環

      主站蜘蛛池模板: 78成人精品电影在线播放日韩精品电影一区亚洲 | 国产精品亚洲不卡一区二区三区| 久久中文字幕无码一区二区| 亚洲乱码日产一区三区| 乱人伦一区二区三区| 韩国精品一区二区三区无码视频 | 亚洲天堂一区二区| 国产在线观看一区二区三区精品| 成人免费一区二区无码视频| 国产高清一区二区三区| 肉色超薄丝袜脚交一区二区| 国产AV午夜精品一区二区三区| 精品国产一区二区三区2021| 无码人妻精品一区二区蜜桃百度| 午夜爽爽性刺激一区二区视频| 欧美日韩一区二区成人午夜电影| AV无码精品一区二区三区| 日韩免费无码视频一区二区三区 | 国产午夜精品一区理论片飘花| 国产一区二区三区四| 国产一区风间由美在线观看| 国产精品综合一区二区三区| 国产成人av一区二区三区在线 | 91福利国产在线观看一区二区 | 国产成人无码精品一区二区三区 | 人妻无码一区二区视频| 一区三区三区不卡| 国产成人久久精品麻豆一区| 中文字幕一区二区三区日韩精品| 久久久国产一区二区三区| 日韩精品无码一区二区三区AV | 亚洲av不卡一区二区三区| 亚洲国产老鸭窝一区二区三区| 亚洲一区二区三区四区视频| 日本一区二区三区不卡视频| 国产成人精品视频一区| 波多野结衣的AV一区二区三区| 国产亚洲一区二区精品| 精品国产鲁一鲁一区二区 | 国产伦精品一区二区三区| 久久久久无码国产精品一区|