Repeat the wheel-experience in improving the performance of XLinq and improving the performance of xlinq

Source: Internet
Author: User

Repeat the wheel-experience in improving the performance of XLinq and improving the performance of xlinq
Two mountains

1. EF

When I first came into contact with linq, I felt this guy was amazing, his syntax was beautiful, and he was very good. Later, I went through some bad things of EF and wanted to make up for it. Since I wanted to make up for it, I had to understand the principle. IQueryProvider was not fully understood at the very beginning or even for a long time. IQueryProvider was not easy to understand, at this time, I tried to write the first ORM. At that time, I did not understand the principle of the Expression Tree. Naturally, the idea at the beginning was to calculate a little bit, and I couldn't go back because the idea was too messy. At this time, I feel that EF is too good, so complicated linq can be translated. Although the quality of the translated SQL statements is not good and there is still a pitfall, at least it is translated, I feel that I can never do it.

2. Dapper

This framework is well-known and has a high performance. The underlying layer is written in EMIT. However, I am a technical exclusive person. If I develop it myself, if this tool makes me feel uncomfortable, I will try to develop it myself. So I didn't use dapper either, because it directly operates the Connection and needs to write the SQL code. However, what I write myself is always hard on performance, and it cannot be compared with dapper. Previously, I used expression tree in my spare time to convert DataSet to List, and then got the company's installation force. My colleague came up with the following sentence: "Come here to compare with dapper ", I said, "If you don't want to abuse me, it's worse than the result. At that time, I thought it was impossible for me to achieve the dapper conversion speed.

Performance Improvement Test

Test code

Test Results

The second EF is correct, but the dapper basically has the same performance. Ignore the gap.

It was also performed once before and was dapper second, which has the same performance as EF because of dictionary cache problems.

In this case, the dapper is actually given to the second in the first place, which is nearly half of the dapper. However, it was found that the situation was not fully considered, it's almost the same if you think about it all.

Insights and experiencesIDataReader to List key code 1 public static Func <IDataReader, IList> GetDataReaderMapeer (Type type, IDataReader reader) 2 {3 Func <IDataReader, IList> func = null; 4 if (! _ DataReader2ListCahce. TryGetValue (type, out func) 5 {6 lock (_ dataReader2ListCahce) 7 {8 if (! _ DataReader2ListCahce. tryGetValue (type, out func) 9 {10 var readerExp = Expression. parameter (ReflectorConsts. IDataReaderType, "reader"); 11 var properties = ExpressionReflector. getProperties (type); 12 var fieldCount = reader. fieldCount; 13 var expressions = new List <Expression> (); 14 var objVar = Expression. variable (type, "entity"); 15 var fieldCountVar = Expression. variable (ReflectorConsts. int32Type, "fieldCount"); 16 var readerVar = Expression. variable (ReflectorConsts. IDataReaderType, "readerVar"); 17 var propertyNameArr = Expression. variable (ReflectorConsts. stringArrayType, "pis"); 18 var indexArrVar = Expression. variable (ReflectorConsts. int32ArrayType, "indexes"); 19 var readIndexVar = Expression. variable (ReflectorConsts. int32Type, "readIndex"); 20 var indexVar = Expression. variable (ReflectorConsts. int32Type, "index"); 21 var forBreakLabel = Expression. label ("forBreak"); 22 var assignIndexVar = Expression. assign (indexVar, Expression. constant (0); 23 var listType = ReflectorConsts. listType. makeGenericType (type); 24 var listVar = Expression. variable (listType, "list"); 25 expressions. add (Expression. assign (listVar, Expression. new (listType); 26 expressions. add (Expression. assign (readerVar, readerExp); 27 expressions. add (assignIndexVar); 28 var assignFieldCountVar = Expression. assign (fieldCountVar, 29 Expression. makeMemberAccess (readerVar, ReflectorConsts. fieldCountOfIDataReader) 30); 31 expressions. add (assignFieldCountVar); 32 var readNameExp = Expression. call (readerVar, ReflectorConsts. getOrdinalOfIDataReader, Expression. arrayIndex (propertyNameArr, indexVar); 33 var initIndexArray = Expression. assign (indexArrVar, Expression. newArrayBounds (ReflectorConsts. int32Type, Expression. constant (fieldCount); 34 var initPropertyArrayExpressions = new List <Expression> (); 35 for (int I = 0; I <fieldCount; I ++) 36 {37 initPropertyArrayExpressions. add (Expression. constant (reader. getName (I); 38} 39 var initPropertyArray = Expression. assign (propertyNameArr, Expression. newArrayInit (ReflectorConsts. stringType, initPropertyArrayExpressions); 40 var assignIndexArrayVar = Expression. assign (Expression. arrayAccess (indexArrVar, indexVar), readNameExp); 41 expressions. add (initPropertyArray); 42 expressions. add (initIndexArray); 43 expressions. add (Expression. loop (44 Expression. ifThenElse (45 Expression. lessThan (indexVar, fieldCountVar), 46 Expression. block (47 assignIndexArrayVar, 48 Expression. assign (49 indexVar, 50 Expression. add (indexVar, Expression. constant (1) 51) 52), 53 Expression. break (forBreakLabel) 54), 55 forBreakLabel 56); 57 Expression body = null; 58 DataReaderGetMethodSwitcher switcher = null; 59 var labelTarget = Expression. label (type, "return"); 60 var paramterExpressions = new List <ParameterExpression> (); 61 var setEntityExpressions = new List <Expression> (); 62 if (TypeHelper. isCompilerGenerated (type) 63 {64 var constructor = type. getConstructors (). firstOrDefault (); 65 if (constructor = null) 66 {67 throw new ArgumentException ("type" + type. fullName + "No constructor found"); 68} 69 var parameters = constructor. getParameters (); 70 var expressionParams = new List <ParameterExpression> (); 71 for (int I = 0; I <fieldCount; I ++) 72 {73 var parameter = parameters [I]; 74 var parameterVar = Expression. variable (parameter. parameterType, parameter. name); 75 var parameterType = TypeHelper. getUnderlyingType (parameter. parameterType); 76 switcher = new DataReaderGetMethodSwitcher (parameterType, readIndexVar, readerVar); 77 switcher. process (); 78 var rightExp = (Expression) switcher. result; 79 if (TypeHelper. isNullableType (parameter. parameterType) 80 {81 rightExp = Expression. convert (rightExp, parameter. parameterType); 82} 83 var isNullExp = Expression. call (readerExp, ReflectorConsts. isDBNullfIDataReader, readIndexVar); 84 var ifExp = Expression. ifThenElse (isNullExp, Expression. assign (parameterVar, Expression. default (parameter. parameterType), Expression. assign (parameterVar, rightExp); 85 var exps = new List <Expression> (); 86 setEntityExpressions. add (87 Expression. assign (88 readIndexVar, 89 Expression. arrayIndex (indexArrVar, Expression. constant (I) 90) 91); 92 setEntityExpressions. add (ifExp); 93 expressionParams. add (parameterVar); 94} 95 setEntityExpressions. add (Expression. assign (objVar, Expression. new (constructor, expressionParams); 96 paramterExpressions. addRange (expressionParams); 97 paramterExpressions. add (readerVar); 98 paramterExpressions. add (listVar); 99} 100 else101 {102 var newExp = Expression. new (type); 103 setEntityExpressions. add (Expression. assign (objVar, newExp); 104 for (int I = 0; I <fieldCount; I ++) 105 {106 var propertyName = reader. getName (I); 107 var property = properties. get (propertyName); 108 if (property = null) 109 {110 continue; 111} 112 var propertyAssignExpressions = new List <Expression> (); 113 var propertyExp = Expression. property (objVar, property); 114 var propertyType = TypeHelper. getUnderlyingType (property. propertyType); 115 Expression rightExp = null; 116 switcher = new DataReaderGetMethodSwitcher (propertyType, readIndexVar, readerVar); 117 switcher. process (); 118 rightExp = (Expression) switcher. results; 119 if (TypeHelper. isNullableType (property. propertyType) 120 {121 rightExp = Expression. convert (rightExp, property. propertyType); 122} 123 setEntityExpressions. add (124 Expression. assign (125 readIndexVar, 126 Expression. arrayIndex (indexArrVar, Expression. constant (I) 127) 128); 129 var ifExp = Expression. ifthen( 130 Expression. not (131 Expression. call (readerExp, ReflectorConsts. isDBNullfIDataReader, readIndexVar) 132), 133 Expression. assign (propertyExp, rightExp) 134); 135 setEntityExpressions. add (ifExp); 136} 137 paramterExpressions. add (listVar); 138 paramterExpressions. add (readerVar); 139} 140 paramterExpressions. add (indexVar); 141 paramterExpressions. add (propertyNameArr); 142 paramterExpressions. add (fieldCountVar); 143 paramterExpressions. add (indexArrVar); 144 paramterExpressions. add (readIndexVar); 145 // expressions. add (Expression. call (146 // null, 147 // typeof (MessageBox ). getMethod ("Show", new Type [] {ReflectorConsts. stringType}), 148 // Expression. call (149 // null, 150 // ReflectorConsts. convertToStringMethod, 151 // Expression. convert (152 // Expression. arrayIndex (indexArrVar, Expression. constant (1), 153 // ReflectorConsts. objectType) 154 //); 155 setEntityExpressions. add (Expression. call (listVar, listType. getMethods (). firstOrDefault (x => x. name = "Add"), objVar); 156 expressions. add (157 Expression. loop (158 Expression. block (159 Expression. ifThenElse (160 Expression. call (readerVar, ReflectorConsts. readOfIDataReader), 161 Expression. block (new [] {objVar}, setEntityExpressions), 162 Expression. break (labelTarget, Expression. default (type) 163) 164), 165 labelTarget166); 167 expressions. add (listVar); 168 body = Expression. block (169 paramterExpressions, 170 expressions171); 172 func = Expression. lambda <Func <IDataReader, IList> (body, readerExp ). compile (); 173 _ dataReader2ListCahce. add (type, func); 174} 175} 176} 177 return func; 178}View Code

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.