完善主體資料,免費(fèi)贈(zèng)送VIP會(huì)員!
    * 主體類型
    * 企業(yè)名稱
    * 信用代碼
    * 所在行業(yè)
    * 企業(yè)規(guī)模
    * 所在職位
    * 姓名
    * 所在行業(yè)
    * 學(xué)歷
    * 工作性質(zhì)
    請(qǐng)先選擇行業(yè)
    您還可以選擇以下福利:
    行業(yè)福利,領(lǐng)完即止!

    下載app免費(fèi)領(lǐng)取會(huì)員

    NULL

    ad.jpg

    二次開發(fā)教程:orm 里使用Emit

    發(fā)布于:2019-07-24 16:33:26

    網(wǎng)友投稿

    更多

    比較一下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++)

                {

                    ///讀數(shù)據(jù)

                    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}";

            }

        }

    }

    輸出結(jié)果為


    反射時(shí)間2725


    Emit 時(shí)間1745


    直接賦值1604

    本文版權(quán)歸腿腿教學(xué)網(wǎng)及原創(chuàng)作者所有,未經(jīng)授權(quán),謝絕轉(zhuǎn)載。

    未標(biāo)題-1.jpg

    上一篇:二次開發(fā)教程:Dapper里使用Attribute自定義映射關(guān)系

    下一篇:二次開發(fā)教程:Emit 循環(huán)

    60acb4e0ef112.png
    主站蜘蛛池模板: 色系一区二区三区四区五区| 亚洲高清一区二区三区| 日本一区二区三区日本免费| 制服中文字幕一区二区| 精品动漫一区二区无遮挡| 无码人妻精品一区二区三区夜夜嗨| 久久青青草原一区二区| 性无码免费一区二区三区在线| 国产精品成人国产乱一区| 成人精品一区二区三区电影| 日韩国产免费一区二区三区| 亚洲丰满熟女一区二区v| 亚洲AV无码一区东京热| 精品国产免费一区二区三区香蕉| 国产精品毛片a∨一区二区三区| 国产传媒一区二区三区呀| 国产精品亚洲一区二区无码| 在线成人综合色一区| 蜜芽亚洲av无码一区二区三区| 国产99久久精品一区二区| 国产精品高清一区二区三区不卡| 国产一区二区视频在线观看| 中文字幕精品无码一区二区三区| 国产激情一区二区三区成人91| 日本美女一区二区三区| 一区二区三区免费视频播放器| 久久一区二区免费播放| 夜夜添无码试看一区二区三区 | 一区二区三区视频网站| 免费一区二区无码视频在线播放| 日本一区二区三区不卡视频中文字幕| 国产一区二区在线观看麻豆| 一区二区三区日本视频| 久久成人国产精品一区二区| 亚洲国产成人一区二区精品区| 亚洲熟妇av一区| 无码夜色一区二区三区| 视频一区二区在线播放| 国产一区二区三区乱码| 亚洲视频一区二区三区四区| 日韩精品国产一区|