Check out my new course Learn you some Lambda best practice for great good! and learn the best practices for performance, cost, security, resilience, observability and scalability.
I stumbled across some interesting discussions on how they differ from non-static methods, here’s a summary of what I learnt.
The Static Keyword
In C# terms, “static” means “relating to the type itself, rather than an instance of the type”. You access a static member using the type name instead of a reference or a value, e.g. Guid.NewGuid().
In addition to methods and variables, you can also declare a class to be static (since C# 2.0). A static class cannot be instantiated and can only contain static members. There are a few rules around static classes:
- Static classes always derive from object, you can’t specify a different base type
- Static classes cannot implement an interface
- Static classes cannot have any instance members
- Static classes can’t declare any constructors and the compiler doesn’t create a parameterless constructor by default
- Static classes are implicitly abstract, you can’t add the abstract modifier yourself
- Static classes may be generic
- Static classes may be nested, in either non-static or static classes
- Static classes may have nested types, either non-static or static
- Only static, top-level non-generic classes can contain extension methods (C# 3.0)
This quote from DotNetPerls’s page on static method just about sums everything up:
Here we note that static methods are normally faster to invoke on the call stack than instance methods. There are several reasons for this in the C# programming language. Instance methods actually use the ‘this’ instance pointer as the first parameter, so an instance method will always have that overhead. Instance methods are also implemented with the callvirt instruction in the intermediate language, which imposes a slight overhead. Please note that changing your methods to static methods is unlikely to help much on ambitious performance goals, but it can help a tiny bit and possibly lead to further reductions.
The article on CA1823 (see References section) offers some insight into the ‘overhead’ mentioned above:
After you mark the methods as static, the compiler will emit nonvirtual call sites to these members. Emitting nonvirtual call sites will prevent a check at runtime for each call that makes sure that the current object pointer is non-null. This can achieve a measurable performance gain for performance-sensitive code.
As stated above, in any real world application you’re not likely to ever feel the difference in performance when you convert non-static methods to static or vice versa. If your application is not performing to the level you have come to expect then I’d recommend using a profiler and get an accurate picture of what’s going inside your code at runtime. I have used both RedGate’s ANTS profiler and JetBrains’ DotTrace and both will do the job more than sufficiently!
Scott Wisniewski said in his answer to this StackOverflow question that in a large project (roughly defined as a project with over 200k lines of code) you should avoid making methods that ‘can be made static’ static because:
In a large code base, however, the sheer number of call sites might make searching to see if it’s possible to convert a static method to a non static one too costly. Many times people will see the number of calls, and say “ok… I better not change this method, but instead create a new one that does what I need”.
Whilst this statement certainly has some truth to it, avoiding static methods should never be the solution to this particular problem, especially when you consider that there are some very good productivity tools out there that can do this for you! So if you don’t want to waste precious man hours on identifying methods to be made static then you should seriously consider purchasing tools such as Resharper.
Static classes on the hand, impose a few more restrictions (in The Static Keyword section above) which make them difficult to incorporate within a highly flexible structure as they cannot implement interfaces and do not support polymorphism (cannot derive from a base type). See Mark Rasmussen’s answer to this StackOverflow question, he goes into detail on a number of drawbacks with using static classes.
I specialise in rapidly transitioning teams to serverless and building production-ready services on AWS.
Are you struggling with serverless or need guidance on best practices? Do you want someone to review your architecture and help you avoid costly mistakes down the line? Whatever the case, I’m here to help.
Check out my new course, Learn you some Lambda best practice for great good! In this course, you will learn best practices for working with AWS Lambda in terms of performance, cost, security, scalability, resilience and observability. Enrol now and enjoy a special preorder price of £9.99 (~$13).
Are you working with Serverless and looking for expert training to level-up your skills? Or are you looking for a solid foundation to start from? Look no further, register for my Production-Ready Serverless workshop to learn how to build production-grade Serverless applications!
Here is a complete list of all my posts on serverless and AWS Lambda. In the meantime, here are a few of my most popular blog posts.
- Lambda optimization tip – enable HTTP keep-alive
- You are thinking about serverless costs all wrong
- Many faced threats to Serverless security
- We can do better than percentile latencies
- I’m afraid you’re thinking about AWS Lambda cold starts all wrong
- Yubl’s road to Serverless
- AWS Lambda – should you have few monolithic functions or many single-purposed functions?
- AWS Lambda – compare coldstart time with different languages, memory and code sizes
- Guys, we’re doing pagination wrong