Dapper vs. EF or NHibernate

I'm working on a smaller project at the moment, and I didn't really want to bother with something as big as EF or NHibernate for my DB. Especially since the database is really more of a true "just a persistence layer" in this application (it runs in memory and the DB is just for long term storage). On top of that, it is just 5 tables. So I decided to take a look at Dapper.

Initially impressions? I kind of like it. I'm sure I'll find little "quality of life" features I'm missing and which might be a pain in a larger application. But, I honestly have to say that whether or not Dapper is an ORM, it is still "just enough ORM". Basically, as long as the columns in the result set match your data structure it does just fine at mapping it. And that is good enough for some scenarios. Like this one.

Then, as far as generating the queries, I've added some attributes to my objects which allow me to use reflection to build the queries on the fly. And I could always cache those once generated or use something like a code generator to have them pre-built. Basically, I have options to speed it up further. Just no necessary at present to do so.

I've also reached a point where I appreciate being responsible and exposed to the underlying Query Languages a bit more directly. While there is certainly something to say for how NHibernate and EF can abstract away the complexity most of the time, I've never run into a large scale production app where you could totally avoid executing raw queries through the ORM, either because it can't support what you want directly or because it wouldn't do it as efficiently as required.

All of this being said, I won't be switching to Dapper for all of my projects. The reality is that NHibernate and EF Core are actually much better than most developers at optimizing most queries. People randomly spout about "overhead" and make assumptions about how queries are generated. 

The truth is, while there is overhead. Most development teams aren't riddled with database experts and most queries are not properly reviewed and almost never optimized.

I can certainly appreciate that Dapper allows me to be faster than other ORMs, but the reality is that, left entirely on my own, I would likely write queries which perform more slowly than EF/NH. And not because I can't write better queries, but either because EF/NH would write the most efficient query or (more likely) because I wouldn't be able to justify the time to optimize every single query to be faster than what they would give me out of the box.

All of that being said, for a service with a small enough domain where it is a lot more feasible to be able to spend the time optimize the queries, Dapper is pretty darn attractive.

My honest opinion of ORMs is simple. Overhead tends to be static and in most cases not sufficient on its own to deter usage. There is a table on the GitHub page for Dapper comparing performance. And while Dapper is indeed fast, the other application are also pulling times measure in MICROSECONDS! Most problems related to performance with that level of overhead can be overcome by scaling vertically or horizontally. If the overhead continues to cause issues, then you're really more reaching the limits of your DB and switching to something a little bit faster is just a temporary fix.

My suggestion, as usual, would be this; if you know the performance characteristics of your application, choose the persistence layer which best matches your needs. If you don't know for sure, then seek out ways to ensure you the skillset and preparation to switch down the road. If, for instance, you had built a system using hybrid microservices, and one relied on Dapper and one on EF, then you would have the skillset and understanding to switch from one to the other. I don't recommend mixing within the same codebase though. That tends to be a cluster-f^%$.

Comments

Popular Posts