I have noticed that it is almost always possible to make a method be static or local. Right now, I am working on the assumption that methods should be local when (I think) it doesn’t make the program run slower because I need to either run it in a loop, return an array or both, and static whenever that’s not the case, but I am not sure if there is more to it than that.


The general rule is to use static methods when your method is a pure function, i.e. a method that doesn’t change anything outside of itself and that always produces the same output for a given input.
A static method must not require an instance of the class, it can be called directly on the class itself. That is true if it doesn’t rely on any instance fields. It can use static fields, but use those with care. Make it static if it can be static.
A local method is just limited in scope.
It is rare that you need to worry about the performance penalty (if any) of calling a method.
I wouldn’t say that, it depends where that function call ends up 😉
“I have noticed that it is almost always possible to make a method be static or local”
That is almost correct, Any class’s method implies first parameter “this”. The rest is just compiler’s trick.
translates to
Virtual methods are tricky a bit, Any object instance has a “virtual” lookup table associated with it. So any call to virtual method need extra lookup into that table to call appropriate method. But again $this will be passed as a first parameter.

Since static methods do not need an instance, the rule “static method can not be virtual” is a consequence of this. Since there is no instance, there is no “virtual” lookup table. That is why you are “almost” correct. virtual methods can not be replaced with static methods.
————————————————————————-
PS: Because you have mentioned performance. From what i said, calling instance method vs static method does have small performance implication (one extra parameter $this is passed). Calling virtual method requires additional lookup.
But performance gain/loss is so negligible, the additional runtime takes about 2-4 ticks (CPU tick) and one tick is about 10 nanoseconds. So you do the math.

Edit: For example, a 4 GHz processor performs 4,000,000,000 clock cycles (tick) per second
Operation to pass parameter will add about 4 ticks. Meaning 4 GHz CPU can do it 1 billion times in a second. And i am talking only about 1 core.
When you don’t need to create instance of the class.
When you want to create extension method for specified type.
It probably sounds like circular reasoning for me to say this, but I use static methods for things that probably won’t be related to a specific instance of a class. To be fair, there ARE ways in which the same function could be written so as to be static or not static.
Unambiguously static: You have some Graph class that models a cartesian graph which you can fill with things (maybe you’re making a chess simulator or something.) You have a function called ManhattanDistance which returns the Manhattan distance between two points. This would definitely be static. You don’t need to know ANYTHING about a specific graph.
Unambiguously instance: Let’s keep our Graph example from above. Suppose your graph is actually a maze, and you have a pathfinding algorithm that returns a path between two points. The path is completely dependent upon what is populated inside a specific instance of Graph, and therefore you’ll be using those member variables to figure out what the resulting path will be.


Where this starts to get a little messy: You may find that an instance method only uses one member variable from a class. If that’s the case, you can totally get away with turning that member variable into an argument and making the method static instead. However, if you find yourself needing more and more arguments, all of which are member variables from the same instance, it’s time to make it an instance method. There may be some hard and fast rules to when to make something static or instance in this case, but usually I try and guesstimate based on how I think I’ll use that specific method.
When a method has use without an instance of the class, make it static. Factory-methods have to be static. Helper methods can be static.
C# devs
null reference exceptions

source