完善主體資料,免費贈送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无码一区二区老年| 国产亚洲日韩一区二区三区| 日韩精品无码Av一区二区| 国产精品资源一区二区| 成人国产精品一区二区网站公司 | 精品一区二区三区| 国产精品香蕉在线一区| 精品欧洲av无码一区二区| 久久国产免费一区二区三区 | 国产自产V一区二区三区C| 国产日韩高清一区二区三区| 国产成人一区二区精品非洲| 福利国产微拍广场一区视频在线| 中文字幕日韩丝袜一区| 99精品一区二区三区无码吞精 | 日本一区二区三区在线观看视频| 精品深夜AV无码一区二区老年 | 国产一区二区三区在线免费观看 | 亚洲AV无码一区二三区| 色系一区二区三区四区五区| 国产麻豆剧果冻传媒一区| 日韩一区二区三区免费体验| 精品国产高清自在线一区二区三区| 大香伊人久久精品一区二区| 亚洲AV无码一区二区大桥未久| 国产怡春院无码一区二区 | 免费视频精品一区二区| 亚洲国产成人精品久久久国产成人一区二区三区综 |