Think, don’t be f#cking Lazy<T>

Dmytro Zhluktenko
3 min readJul 25, 2017

--

Let me tell you a story. Sit and listen.
Every day millions of developers write billions lines of code. Someone is reviewing this code. Someone is not writing yet, just being curious what decision to make, what pattern to use. Everything tends to contributing a good code to software product they are working on.

And then suddenly this happens to your codebase:

Why? The casual answer would be “ah, it has been written before and there was no need to touch or move it.” It’s very casual for outsource projects.
I say that every decision you make on writing software should be technically justified, it’s not like “ah, i feel like it so let this thing be here”.

The most important aspect of software engineering is to describe the intent of change. We must describe the why. This is what we must do as professionals.

But, whatever, I spent like two evenings trying to figure out why the previous developer made such a thing to this project. So, let’s dig in:

Lazy<T> is a concept where we delay creating of the object to the moment we literally need it, so to speak to the moment when we can’t go further without that.

Seems like we can increase startup time in that way and increase our performance at all, isn’t it?

Ok, this side. Listen.
+ Minimize startup time of the application.
+ Less memory may be used ‘cuz of on-demand loading.
+ Heavy object performance gain

But if you are curious about delay and performance, just think a bit about where the real costs come in the game: web services, databases or the file system. They have slightly bigger delay than a casual repository. All these pros are pretty abstract and need to be explored and explained.

Why people do this kind of things?
I assume that it’s done on purpose, but it’s still unknown to me, even after few research evenings.

However, a Lazy<T> just consumes 20 bytes of memory (and another 24 bytes for its wrapped Func<T>, assuming a 32bit process), and the creation of a Lazy<T> instance is practically free.

And I think that constructor should do no more than storing the dependencies injected from parameters. And creating a repository is very fast and usually never the bottleneck. What’s the point of laziness here then?

What I find bad about Lazy<T> approach:

Your code becomes complicated. e.g. userRepository.Value.Get(…). It’s simple as ABC — more symbols, but less informative.

From a Dependency Injection perspective, Lazy<T> is a leaky abstraction. Here is a great explanation of that.

Basically, it can reduce startup times in your C# programs in cases where its overhead is dwarfed by the cost of the initialization.

So is it a post about Lazy pattern in software engineering? Totally not.

I’m talking about following Decision Driven Development or so to say Choice Driven Development.
You don’t just write some random code, you are doing decisions and they should be valuable and understandable. You are doing decisions every day, few for a day for sure, but stop for a minute and think about each of it. Think of your decision. Do you have alternative ways to do it? Is it easy to understand your logic to make this decision? Is it a hard decision? If so, maybe it should be documented? And so on.

It’s not about code, it’s about software thinking.
Your decisions must be justified to be committed.

--

--

Dmytro Zhluktenko
Dmytro Zhluktenko

Written by Dmytro Zhluktenko

Ukraine, Lviv. Young & mad. IT, .NET, F#, C#, Azure, software developer. Leading @lvivdotnet. Traveling, seeing things, living life.

No responses yet