EntityFramework, Dapper vs grassroots framework performance RIP
There are many ORM on the market, there are sports car type, such as Dapper, have a good type, such as mybatis.net, also have weight type, such as EntityFramework and NHibernate, there are some from the hands of the grassroots, such as Chloe.orm. Various, endless. Why do we have to reinvent the wheel? Very simple, we are from Mars, there is no wheel on the earth for this Mars car ~
In order to deepen the understanding of the various ORM framework, but also want to see how our own framework performance, but also to Chloe interested students have some knowledge, today, do a performance comparison test. The test object is familiar to everyone entityframework and has "King of performance" of the Dapper, as well as grassroots framework chloe.orm.
Navigation
- Basic introduction
- Test content
- Test metrics
- test environment and preparation
- Test scenarios
- Mapping capability test
- Query capability Testing
- Evaluation Summary
- About Chloe.orm
- Conclusion
Basic introduction
- EntityFramework: EntityFramework is Microsoft's official ORM, commonly known as EF, has an impregnable backstage, no one knows, no one xiao. Its perfect support for LINQ, feature-rich, but EntityFramework Core before the version, has been the industry's people have been affixed to the cumbersome, uncontrollable, poor performance of the label, many people hold it. Visible, entityframework bole not much Ah! Do not know how much entityframework Core changes, look forward to! This article tests the version that is used by EntityFramework 6.1.
- Dapper: Dapper background is also not simple, currently supporting the foreign well-known website StackOverflow data Access layer, its popularity is also very high. In many ORM, it is the king of performance. As a miniature ORM, very popular with domestic developers, after all, after the big website StackOverflow test. Many self-developed ORM do performance testing, will choose Dapper as the comparison object. Chloe.orm is no exception, haha!
- chloe.orm: Grassroots frame, newborn calf. Click here for more information ...
Test content
This time only for each ORM query efficiency to do the evaluation. The performance loss of ORM is mainly in the process of DataReader to entity and generating SQL statements, so the content of this test examines the following two aspects:
1. Mapping capabilities.
2. Query capabilities (because the performance of the SQL generation phase cannot be tested, this test includes SQL generation and mapping capabilities), which is a complete query.
Test metrics
1. Speed. That is, when the same query is executed.
2. Number of GC recoveries. That is, perform the same query GC to perform the collection. The more GC times, the greater the memory overhead of the program running. This indicator test through VS2013 's own performance analysis tool, it can automatically help us to analyze the statistics program run allocated memory and GC recovery times, do not understand the students can go to understand. Opens VS, analyzes performance and diagnostics--memory usage.
test environment and preparation
machine : Dell XPS13 Notebook, CPU is i7-4510u, memory 8g,win 10 system.
Table :
CREATE TABLE [dbo]. [Testentity] ([Id] [int] IDENTITY () not null,[f_byte] [tinyint] null,[f_int16] [smallint] null,[f_int32] [int] null,[f_int64] [Bigi NT] null,[f_double] [float] null,[f_float] [real] null,[f_decimal] [Decimal] (0) Null,[f_bool] [bit] Null,[f_datetime ] [datetime] null,[f_guid] [uniqueidentifier] null,[f_string] [nvarchar] (+) NULL, CONSTRAINT [pk_test] PRIMARY KEY clus tered ([Id] ASC) with (Pad_index = off, Statistics_norecompute = off, Ignore_dup_key = off, Allow_row_locks = ON, allow_page _locks = ON) on [PRIMARY]) on [PRIMARY]
Data Preparation :
Insert 1 million data into the Testentity table.
DECLARE @i int = 0;begin Tran;while (@i<=1000000) Begininsert into [dbo]. [Testentity] ([F_byte] , [f_int16], [F_int32] , [F_int64] , [f_double] , [f_float] , [F_decimal] , [ F_bool] , [f_datetime] , [F_guid] , [f_string]) VALUES (1 , 2 , @i , @i , @i , @i , @i , @i%2 , GETDATE () , NEWID () , ' Chloe ' + CAST (@i as nvarchar (1000)) ) set @[email protected]+1;endcommit;
Test Scenario 1. Mapping Capability test
The mapping ability refers to the DataReader to the entity transformation, this process has many ways, the mainstream is the reflection and the Emit dynamic generation delegate two kinds of ways. The performance of the reflection is relatively poor, it is understood that the early batch of ORM mostly with reflection, and then everyone realized that the reflection performance problem, basically all turn Emit or in other ways replaced. To reduce the impact of other aspects of the program on the test results, the solution I designed is to query N data at a time, without any where condition, so as to improve the mapping performance loss in the overall test ratio, reduce other aspects (Database execution query, SQL generation, etc.) on the test results in the overall test performance impact ratio, In summary, the larger the N value, the smaller the effect of the additional factors on the test results, the more realistic the data. In this test, I choose to check 500,000 data at a time. Test code:
View Code
Run:
To be fair, all tests are run in non-Debug mode and are preheated. For a total of 5 rounds, the following is the test result data:
|
Chloequerytest (MS) |
Chloesqlquerytest (MS) |
Dapperquerytest (MS) |
Eflinqquerytest (MS) |
Efsqlquerytest (MS) |
1th Round |
6976 |
7170 |
39°8 |
7704 |
7744 |
2nd round |
7357 |
6853 |
8410 |
8328 |
7783 |
3rd Round |
7610 |
7833 |
8107 |
9795 |
8706 |
4th round |
7296 |
6957 |
7760 |
8643 |
7873 |
5th round |
9636 |
6705 |
8805 |
8946 |
8544 |
Average |
7775 |
7103 |
8206 |
8683 |
8130 |
The above table is a simple test time, the following is a query 500,000 data, the number of GC times.
Run:
GC statistics result, because the same code runs, memory allocations and GC conditions are the same, so this test does not have to run multiple rounds:
|
Chloequerytest |
Chloesqlquerytest |
Dapperquerytest |
Eflinqquerytest |
Efsqlquerytest |
GC Recycle times |
22 |
22 |
38 |
40 |
35 |
Can be seen, chloe.orm in all aspects of a slightly superior, see this result, it is estimated that everyone is not possible. After all, some people like to raise eyebrows outside, foreign moon than the domestic circle. Start to see this result I also feel a bit strange, later turned to see Dapper source code, found that Chloe a little faster is unexpectedly, but also in the sense. EF mapping mode I didn't know that Chloe and Dapper both create entities and attribute assignments with Emit to generate delegates, and there's no difference in performance. But the difference is that Chloe read data from DataReader is called strongly typed methods (GetInt (int i), getdatetime (int i), GetString (int i) ... ), so the reading of value-type data avoids boxing and unpacking, thus reducing the number of garbage objects, with fewer GC times. Dapper Otherwise, it reads data from DataReader using Datareader[int i], its internal implementation is to call Datareader.getvalue (int i), if it is a value type of data, will cause a lot of boxing and unboxing, need CPU Large amounts of computation also generate a lot of garbage objects, with the number of GC increases. I think that's why Chloe is notch above in mapping. As you can see, Chloe has achieved the ultimate in mapping.
In fact, the three in the mapping ability of the gap is not big. In order to see the performance differences, we queried a large amount of data at a time, just to test the effect, in the actual production is not the case.
Conclusion :
1. Speed: Averaging,eflinqquery < Dapperquery≈efsqlquery < Chloequery < Chloesqlquery
2. GC Number:eflinqquery < Dapperquery < efsqlquery< chloequery = Chloesqlquery
2. Query capability test
query capabilities include SQL generation capability and mapping capability, which is a complete query that compares to the actual operation of the program . This test for ORM performance evaluation, in order to reduce the database execution of SQL time-consuming interference, my design is that a query only one data, while testing the resolution of the lambda, add a a.id > Id (0) Where condition, execute multiple queries (this test I choose to execute 2000 0 queries).
Test 2.1:
View Code
Run:
Run 5 times, the following is the time result:
|
Chloequerytest (MS) |
Chloesqlquerytest (MS) |
Dapperquerytest (MS) |
Eflinqquerytest (MS) |
Efsqlquerytest (MS) |
1th Round |
15083 |
12594 |
13134 |
41163 |
24339 |
2nd round |
15597 |
12711 |
12133 |
40294 |
25281 |
3rd Round |
15356 |
11885 |
11587 |
44913 |
25707 |
4th round |
16419 |
13089 |
12803 |
46196 |
25635 |
5th round |
16216 |
12463 |
12221 |
40064 |
23749 |
Average |
15734 |
12548 |
12375 |
42526 |
24942 |
Let's look at the GC situation:
|
Chloequerytest |
Chloesqlquerytest |
Dapperquerytest |
Eflinqquerytest |
Efsqlquerytest |
GC Recycle times |
116 |
47 |
49 |
538 |
359 |
Accidents do not know, a test scare jump. See this result, I ate that what several catty, do not know is my code has the question or how to return a matter, EF incredibly so "passable", good sad.
But looking at the test code of the Test 2.1 and discovering that the loop body contains the code to create the DbContext, I wonder if the EF is so slow because I created DbContext multiple times? Wouldn't it be better if you put the code that created the DbContext in the loop outside the body? So there is the test 2.2.
Test 2.2:
View Code
Run 5 times to get the following results:
|
Chloequerytest (MS) |
Chloesqlquerytest (MS) |
Dapperquerytest (MS) |
Eflinqquerytest (MS) |
Efsqlquerytest (MS) |
1th Round |
15281 |
11858 |
11981 |
31394 |
19309 |
2nd round |
15194 |
12177 |
12314 |
31464 |
18161 |
3rd Round |
15967 |
12348 |
12366 |
31082 |
18030 |
4th round |
15371 |
11793 |
12479 |
32314 |
18356 |
5th round |
15350 |
11921 |
11937 |
35023 |
18356 |
Average |
15411 |
12019 |
12215 |
32255 |
18442 |
GC Status:
111
368
&NBSP; |
chloequerytest |
chloesqlquerytest |
Dapperquerytest |
eflinqquerytest |
efsqlquerytest |
GC Recycle |
125 |
|
| valign= "Top" width= "124" >
205 |
It seems that the test data after the test 2.1 slightly increased the point, the most obvious increase is EF, time is reduced by nearly 10 seconds, the number of GC has been reduced a lot. In this view, the EF creation and destruction of the DbContext context is also a very cost-consuming process. The accident is really not known. However, EF's test results are still unsatisfactory, eflinqquerytest time-consuming is still more than the same as the chloequerytest of the object query, GC times is 3 times times higher than the chloequerytest. And as the EF native SQL query efsqlquerytest in time-consuming, GC times actually worse than Chloequerytest, a bit unreasonable ~ really want to know what is not known inside EF work!
Both Dapperquery and chloesqlquery are native SQL queries, dapperquery slightly faster in test 2.1, but in Test 2.2 chloesqlquery implemented the overtake. Think carefully, in fact, it is not difficult to understand, Chloe DbContext creation will accompany a lot of object creation, also consumes a lot of resources, in the test 2.2, only created a DbContext object, with it, all aspects of promotion is certainly. Chloequery in front of the two are not comparable, after all, the first two did not parse and generate SQL process, chloequery relatively slow that is inevitable. The slow seconds are used to parse the lambda and generate SQL. Fish and Bear paw can not be both, want to get development convenience, performance loss is unavoidable!
EF ... "veritable" slow, do not say, are tears-. Kneel and beg the great God to justify EF!
Conclusion:
1. Speed: Averaging,eflinqquery < Efsqlquery < Chloequery < Chloesqlquery≈dapperquery
2. GC times:eflinqquery < Efsqlquery < Chloequery < Dapperquery < Chloesqlquery
Evaluation Summary
- Mapping capabilities: From the DataReader to the entity conversion process, Dapper and Chloe are all using Emit to dynamically generate delegates, and I believe EF is the same way. Therefore, the creation of entity and attribute assignment is equivalent to 3. But the difference is that Chloe in reading DataReader data to achieve the ultimate, so the mapping conversion performance is relatively higher than Dapper and EF. Dapper and EF are similar. In fact, the speed of the 3 are equivalent, the main difference is in memory overhead.
- Query capability: The query capability is the amount of time and memory overhead that the framework takes to execute a complete query. From Test 2.1 and test 2.2 test Results data, we can see that Dapper and Chloe native SQL query performance is almost the same, the gap is not small, Chloe object-based query is slightly less than the previous two, mainly to generate SQL Process to compare consumption performance. EF "live up to expectations", at the bottom of the posture, whether in the speed or GC times than the previous two is a big difference. EF's mapping capability is actually not bad (as can be known from the mapping Capability test data) and the query speed is slow, without a doubt, the problem occurs before the execution of SQL. However, EF is a perfect support for Linq, and the richness of its capabilities has left many grassroots frameworks behind, with the hope that the EntityFramework Core version will have a significant performance boost.
About Chloe.orm
My development principle is, as long as in my ability scope, does not affect the overall situation, must do to achieve the extreme, this is a kind of pursue. Chloe.orm also some of the areas can be optimized, but the optimization of performance will not be very large, recently busy, also lazy toss. At present, the framework of the overall structure, functions have been stable, and now only support SQL Server, the next development goal is to support MYSQL, students interested in Chloe can join the. NET technology Sharing Group (group number:325936847). In order to prevent some unrelated people, such as mixed in the group, you need to answer questions when applying for dabigatran, as long as you are willing to enter the group! Thank you for your cooperation.
About the source code, there is a lack of annotations and specifications, some classes, methods and variable naming is not very good (English, mishap-), to the source of interest in the students to read a lot of trouble, here say sorry. In the future, I will add some comments as appropriate. Many times, in addition to some extremely critical points, I generally do not write comments, especially in the development phase, code transformation is too frequent, maintenance code at the same time to maintain the corresponding comments, too lucky, I can't. The so-called good code is the best comment, like me lazy people, not accustomed to comments, if the code is not good to write, back to my own reading my own code I can not understand. Therefore, not to write comments, but also to form a self-persecution, prompting me to write the code is neat, elegant, easy to read. If it's necessary, I'll be free later. Article on the Chloe.orm Framework design and implementation of internal architecture.
Conclusion
This test is not trying to prove who is good or bad, just want to understand the performance differences between the various ORM by contrast, so that we can better do technology selection for the project. One thing, there is bound to be the value of its existence, project development, the selection of the appropriate framework is important. Dapper is the king of performance, but it relies heavily on handwritten SQL, development efficiency is low, fault tolerance is not high, if a project is not high-performance requirements, choose a rapid development framework is good, a short period of time to complete the project is the main. All we have to do is maximize the benefits. In fact, not all projects are stackoverflow!. If a project data layer with Dapper or, with EntityFramework, on the same server running, can be perfect operation, users completely feel no difference, why do we not choose to develop high efficiency entityframework? At present, our company part of the project, the user group is not for the public, we are using entityframework, with its development efficiency is high, the project is progressing fast, we have no reason to use other frameworks, very simple.
As a developer, many times the real value is not how well you write your code, how fast the program runs, but how you can bring the most benefits to users, companies, and society in the same time.
PS: All the test code has been synced on GitHub, address: https://github.com/shuxinqin/Chloe/tree/master/ChloePerformanceTest.
EntityFramework, Dapper vs grassroots framework Performance