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

    主站蜘蛛池模板: 影院无码人妻精品一区二区| 亚洲乱色熟女一区二区三区蜜臀| 91在线看片一区国产| 日韩爆乳一区二区无码| 奇米精品视频一区二区三区| 无码人妻精一区二区三区| 亚洲中文字幕无码一区二区三区| 亚洲一区动漫卡通在线播放| 亚洲美女高清一区二区三区| 亚洲av综合av一区二区三区 | 一区二区高清视频在线观看| 韩国福利影视一区二区三区| 日韩人妻无码一区二区三区综合部 | 国内精品视频一区二区八戒| 秋霞无码一区二区| 国产精品乱码一区二区三区 | 日韩人妻无码一区二区三区99| 一区二区三区内射美女毛片| 国产成人无码精品一区不卡| 春暖花开亚洲性无区一区二区| 国产未成女一区二区三区| 久久精品一区二区三区AV| 中文字幕日韩丝袜一区| 精品成人乱色一区二区| 欧美激情一区二区三区成人| 午夜视频一区二区| 无码精品久久一区二区三区 | 久久久久人妻一区精品 | 亚洲国产一区二区三区在线观看| 亚洲AV无码一区二区乱子伦| 久久精品一区二区三区不卡| 一区视频在线播放| 中文日韩字幕一区在线观看| 99精品国产一区二区三区| 久久国产精品一区免费下载| 久久免费精品一区二区| 精品爆乳一区二区三区无码av| 51视频国产精品一区二区| 日本免费一区尤物| 日本大香伊一区二区三区| 91久久精品国产免费一区|