This question already has answers here:
Performance of static methods vs instance methods
(3 answers)
Closed 6 years ago.
Performance-wise is there any difference on doing this?:
public static Class StaticTestClass()
{
public static void Function(object param) => //Do stuff with "param"
}
and this:
public Class ConstructedTestClass()
{
private object classParam;
public ConstructedTestClass(object param)
{
classParam = param;
}
public void Function() => //Do stuff with "classParam"
}
I think that there wouldn't be any performance differece if done it one single time, but what If I have to do it many times, and call Function() many times?
Will having many instances of ConstructedTestClass have a memory impact?
And will calling Function withing StaticTestClass with the parameter have any performance impact?
PS: There are similar questions to this but I can't find one that adresses performance upon many calls.
EDIT: I did some tests and this are the results:
With 1000000000 iterations and Creating a ConstructedClass each iteration.
Static way: 72542ms
Constructed way: 83579ms
In this case the static way is faster, then I tried not creating a class each time Function() is called, this are the results: [100000000 samples]
Static way: 7203ms
Constructed way: 7259ms
In this case there's almost no difference so I guess I can do whatever I like the most since i wont be creating 1000000000 instances of the class.
Technically yes, the static method will be slightly faster per call, because a static method doesn't have to check and see if the object it's attached to (because it's not) has been instantiated. This happens behind the scenes. (Technically there will be other slight overhead to set up the object etc.)
This is not a really good reason under most circumstances to choose one over the other though. They have different purposes. The a static method can't maintain state of internal variables like an object can etc.
In your case I would probably pick the static method. Based on the code you show, you don't have a real need to maintain a reference to the object you want to do something to. Perform a function on it, and be done with it.
With the other approach you have to create an object, then call the method. Furthermore the way it's set up, you have to instantiate a new object for each target object you have to perform the action on, because there is a reference stored in a private variable the method acts on. To me this would be more confusing from a readability perspective.
One difference is, that the generated objects have to be garbage collected. That overhead doesn't occur for the static call.
I tested it for 100000000 iterations:
static version takes ~0.7 seconds
non-static version (creating the instance one time and call the method n
times) takes ~ 0.7 seconds.
non-static version (creating one instance per call) takes ~1.4 seconds.
Related
For example I have some class with one void method in it.
This is my class:
class MyClassTest
{
public void Print()
{
Console.WriteLine("Hello");
}
}
I am new to classes and little confused, is there a difference between these two method calls?
Here is my main method
static void Main(string[] args)
{
//first call
MyClassTest ms = new MyClassTest();
ms.Print();
//second call
new MyClassTest().Print();
}
In the case below you'll want to do this when you want to keep a reference to the constructed object and perform some further operations with it later on.
MyClassTest ms = new MyClassTest();
ms.Print();
Whereas, in the case below you'll only want to do this when you no longer care about the constructed object after construction but are just interested in calling the method Print.
new MyClassTest().Print();
The subtle difference between these two scenarios is that in the case where
the object being referenced performs further operations it will most likely get destroyed later than an object that is no longer referenced i.e. the second example above as the GC (Garbage Collector) will find out that it has no references and therefore decides to get rid of it.
There's no difference, actually. You use the first case when you need to refer to MyTestClass further in your program. You use second case as fire-and-forget. If you plan using second case heavily, it's recommended to make Print method as static.
The IL code shows no difference, except WithInstance method when variable holding reference is loaded onto stack (stloc.0 and ldloc.0 IL instructions):
MyClassTest ms = new MyClassTest();
ms.Print();
new MyClassTest().Print();
Your two calls perform the same semantic operation in c#: the difference is that in your first call, you create the ms variable, which suggests the reader that your intent is to use it again in your code: in fact you are calling ms.Print() after.
Your second call, does not declare any variable, this means that your intent is exactly to call the Print method on a brand new MyClassTest instance only once in your code, and you don't care about the instance your just created.
Side note: when compiling in release mode, the C# compiler will compact and reduce variable usage, therefore your two calls will compile the same and they will be like your second call.
In this particular case, no.
Any time you call a method on a result of another method call, new, property access, etc. as per:
new MyClassTest().Print();
It's akin to if you did:
var temp = new MyClassTest()
temp.Print();
So in this case your two examples are the same.
There are some variants where they differ.
One would be value-type objects that are accessed from array or field access. Here the access might use the address of the actual object rather than making a copy. Now it's possible for the opposite to happen where instead of an implicit temporary local being created and explicit local is removed, but it's not promised. Note that with mutable value-types the code with and without a temporary local are also not semantically the same for these cases (but are for a case closer to your example, where the object is the result of a method call that wasn't a ref return to a ref variable).
Another is when it is inside a yield-using or async method. Here the locals in your method become fields in an object produced (which either implements the IEnumerable<T> and/or IEnumerator<T> for yield or the Task for async) while the "invisible" temporary locals I described above do not. (The compiler could, and likely will in the future, do a better job at getting rid of some of these that don't exist after yield or async calls and therefore don't really have to be fields, but for the time being all the locals become fields).
So there are a few times when explicit locals with a single operation on them are slightly different to doing the operation directly on the means by which you obtained the value, though your example is not one of those times.
I am debating the pros and cons of a couple of utility classes I have. The classes have a couple of properties which are set prior to calling the class methods. However, I was wondering if there are any cons to this approach rather than sending a variable along with the method call? There are typically only one or two methods in these classes.
Thank you.
I don't know what your class looks like, so I'll make a guess...
I assume you have something like that:
public class MyClass
{
public static int X { get; set; }
public static void MyMethod()
{
Console.WriteLine("X = {0}", X);
}
}
And you call it like this:
MyClass.X = 42;
MyClass.MyMethod();
There are at least two problems with this approach:
there is no obvious indication that you need to set X before calling MyMethod
it makes the method non thread-safe: if both thread1 and thread2 are calling it, you can have something like that:
thread1 sets X to 42
thread2 sets X to 99
thread1 calls MyMethod => prints 99 instead of 42
thread2 calls MyMethod => prints 99
A better approach is to pass the value as a parameter to the method:
public class MyClass
{
public static void MyMethod(int x)
{
Console.WriteLine("X = {0}", x);
}
}
And call it like this:
MyClass.MyMethod(42);
This solves the two problems mentioned before:
it's clear than you need to provide the value of x to MyMethod
there is no state stored in the class, so the method is thread-safe
I'd say it mostly depends on how you tend to invoke those methods. There are situations where either approach might be preferred.
When you tend to pass the same values over multiple invocations, it may be more convenient to instantiate a class which holds those values as properties, read-only or writable depending on the exact needs. You can then call your method multiple times conveniently without repeating yourself much. A good example of this is the HttpClient: you configure it once, and then call certain methods multiple times.
This approach also works well if you need to maintain some state between method invocations.
However, by default, if the above considerations do not apply, I would recommend having pure static methods. They are self-contained, they don't behave differently based on relatively external factors (property values set some time ago). You don't need to worry before each call whether you've set the properties correctly, as all the values are passed in. Finally, self-contained methods are easier to understand and use in multi-threading scenarios.
I have a class Meterage which I expect to be instantiated several times, probably in quick succession. Each class will need to know the location of the dropbox folder in the executing machine, and I have code for this.
The class currently has a variable:
private string dropboxPath = string.Empty;
to hold the path, but I am considering making this a static to save repeated execution of
this.LocateDropboxFolder();
in the constructor. But I am a little concerned by the switch: what if two constructors try to set this at the same time? Would this code in the constructor be safe (LocateDropboxFolder becomes static too in this example):
public Meterage()
{
if (dropboxPath == string.Empty)
{
LocateDropboxFolder();
}
}
I think my concerns are perhaps irrelevant as long as I don't have construction occurring in multiple threads?
If the field is made static then static field initializers or static constructors are the easy way to initialize them. This will be executed at most once in a thread safe manner.
private static string dropboxPath;
static Meterage()
{
LocateDropboxFolder();
}
If you don't want to re-assign the field I suggest you to use readonly modifier, then the code should look like:
private static readonly string dropboxPath;
static Meterage()
{
dropboxPath = LocateDropboxFolder();
}
LocateDropboxFolder needs to return a string in this case.
Variables declared outside the constructor are evaluated before the constructor. Then the constructor will evaluate it.
Do remember that you will end up have only one dropBoxPath. If this is intended, it is okay to do so. Optionally, make LocateDropboxFolder a static method and call it from the static constructor.
If you want to prevent other constructors to overwrite the default, try this:
if (string.IsNullOrEmpty(dropboxPath))
{
LocateDropboxFolder();
}
Or, in a static constructor (at most called once):
static Meterage()
{
LocateDropboxFolder();
}
private static LocateDropboxFolder()
{
...
}
Your example will be safe provided your code is executing synchronously. If multiple instances are created, their constructors will be called in the order they are created.
On the first run through, LocateDropboxFolder() will execute. When this completes, dropboxPath will be set.
On the second constructor execution, LocateDropboxFolder() will not execute because dropboxPath will no longer equal string.Empty (provided 'LocateDropboxFolder()' does not return string.Empty.
However, if LocateDropboxFolder() is asynchronous or the objects are instantiated on different threads, then it is possible to create a second Meterage instance before dropBoxPath has been set by the LocateDropboxFolder() function. As such, multiple calls to the function will likely be made.
If you wish to guard against multithreading errors like this, you could consider using lock statements.
You might potentially end up running the LocateDropboxFolder multiple times if the object tries to be constructed multiple times in close succession from multiple threads. As long as the method returns the same result every time though this shouldn't be a problem since it will still be using the same value.
Additionally if you are setting the value of dropboxPath in the constructor then there is no point setting a default value for it. I'd just declare it (and not assign it) and then check for null in your constructor.
I hava a feeling that your Meterage class is breaking a Single Responsibility Principle. What has the meterage to do with a file access? I would say you have 2 concerns here: your Meterage and, let's say, FolderLocator. the second one should have some property or method like Dropbox which could use lazy evaluation pattern. It should be instantiated once and this single instance can be injected to each Metarage instance.
Maybe not FolderLocator but FileSystem with some more methods than just a single property? Nos sure what you're actually doing. Anyway - make an interface for this. That would allow unit testing without using the actual Dropbox folder.
I have a helper method that takes a begin date and an end date and through certain business logic yields an integer result. This helper method is sometimes called in excess of 10,000 times for a given set of data (though this doesn't occur often).
Question:
Considering performance only, is it more efficient to make this helper method as a static method to some helper class, or would it be more gainful to have the helper method as a public method to a class?
Static method example:
// an iterative loop
foreach (var result in results) {
int daysInQueue = HelperClass.CalcDaysInQueue(dtBegin, dtEnd);
}
Public member method example:
// an iterative loop
HelperClass hc = new HelperClass();
foreach (var result in results) {
int daysInQueue = hc.CalcDaysInQueue(dtBegin, dtEnd);
}
Thanks in advance for the help!
When you call an instance method the compiler always invisibly passes one extra parameter, available inside that method under this name. static methods are not called on behalf of any object, thus they don't have this reference.
I see few benefits of marking utility methods as static:
small performance improvement, you don't pay for a reference to this which you don't really use. However I doubt you will ever see the difference.
convenience - you can call static method wherever and whenever you want, the compiler is not forcing you to provide an instance of an object, which is not really needed for that method
readability: instance method should operate on instance's state, not merely on parameters. If it's an instance method not needing an instance to work, it's confusing.
The difference in performance here is effectively nothing. You will have a hard time actually measuring the difference in time (and getting over the "noise" of other stuff going on with your CPU), that's how small it will be.
Unless you happen to go and perform a whole bunch of database queries or read in several gigabytes of info from files in the constructor of the object (I'm assuming here that' it's just empty) it will have a fairly small cost, and since it's out of the loop it doesn't scale at all.
You should be making this decision based on what logically makes sense, not based on performance, until you have a strong reason to believe that there is a significant, and necessary performance gain to be had by violating standard practices/readability/etc.
In this particular case your operation is logically 'static'. There is no state that is used, so there is no need to have an instance of the object, as such the method should be made static. Others have said that it might perform better, which is very possibly true, but that shouldn't be why you make it static. If the operation logically made sense as an instance method you shouldn't try to force it into a static method just to try to get it to run faster; that's learning the wrong lesson here.
Just benchmark it :) In theory a static method should be faster since it leaves out the virtual call overhead but this overhead might not be significant in your case (but I'm not even sure what language the example is in). Just time both loops with a large enough number of iterations for it to take a minute or so and see for yourself. Jut make sure you use non-trivial data so your compiler doesn't optimize the calls out.
Based on my understanding, it would be more beneficial for performance to make it a static method. This means that there isn't an instance of the object created, although the performance difference would be negligible, I think. That is the case if there isn't some data that has to be recreated every time you call the static function, which could be stored in the class object.
You say 'considering performance only'. In that case you should fully focus on whats inside
HelperClass.CalcDaysInQueue(dtBegin, dtEnd);
And not on the 0.0001% of runtime spent in calling that routine. If it's a short routine the JIT compiler will inline it anyway and in that case there will be NO performance difference between the static and instance method.
When creating a class that has internal private methods, usually to reduce code duplication, that don't require the use of any instance fields, are there performance or memory advantages to declaring the method as static?
Example:
foreach (XmlElement element in xmlDoc.DocumentElement.SelectNodes("sample"))
{
string first = GetInnerXml(element, ".//first");
string second = GetInnerXml(element, ".//second");
string third = GetInnerXml(element, ".//third");
}
...
private static string GetInnerXml(XmlElement element, string nodeName)
{
return GetInnerXml(element, nodeName, null);
}
private static string GetInnerXml(XmlElement element, string nodeName, string defaultValue)
{
XmlNode node = element.SelectSingleNode(nodeName);
return node == null ? defaultValue : node.InnerXml;
}
Is there any advantage to declaring the GetInnerXml() methods as static? No opinion responses please, I have an opinion.
From the FxCop rule page on this:
After you mark the methods as static, the compiler will emit non-virtual call sites to these members. Emitting non-virtual call sites will prevent a check at runtime for each call that ensures that the current object pointer is non-null. This can result in a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue.
When I'm writing a class, most methods fall into two categories:
Methods that use/change the current instance's state.
Helper methods that don't use/change the current object's state, but help me compute values I need elsewhere.
Static methods are useful, because just by looking at its signature, you know that the calling it doesn't use or modify the current instance's state.
Take this example:
public class Library
{
private static Book findBook(List<Book> books, string title)
{
// code goes here
}
}
If an instance of library's state ever gets screwed up, and I'm trying to figure out why, I can rule out findBook as the culprit, just from its signature.
I try to communicate as much as I can with a method or function's signature, and this is an excellent way to do that.
A call to a static method generates a call instruction in Microsoft intermediate language (MSIL), whereas a call to an instance method generates a callvirt instruction, which also checks for a null object references. However, most of the time the performance difference between the two is not significant.
Source: MSDN - https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/79b3xss3(v=vs.110)
Yes, the compiler does not need to pass the implicit this pointer to static methods. Even if you don't use it in your instance method, it is still being passed.
It'll be slightly quicker as there is no this parameter passed (although the performance cost of calling the method is probably considerably more than this saving).
I'd say the best reason I can think of for private static methods is that it means you can't accidentally change the object (as there's no this pointer).
This forces you to remember to also declare any class-scoped members the function uses as static as well, which should save the memory of creating those items for each instance.
I very much prefer all private methods to be static unless they really can't be. I would much prefer the following:
public class MyClass
{
private readonly MyDependency _dependency;
public MyClass(MyDependency dependency)
{
_dependency = dependency;
}
public int CalculateHardStuff()
{
var intermediate = StepOne(_dependency);
return StepTwo(intermediate);
}
private static int StepOne(MyDependency dependency)
{
return dependency.GetFirst3Primes().Sum();
}
private static int StepTwo(int intermediate)
{
return (intermediate + 5)/4;
}
}
public class MyDependency
{
public IEnumerable<int> GetFirst3Primes()
{
yield return 2;
yield return 3;
yield return 5;
}
}
over every method accessing the instance field. Why is this? Because as this process of calculating becomes more complex and the class ends up with 15 private helper methods, then I REALLY want to be able to pull them out into a new class that encapsulates a subset of the steps in a semantically meaningful way.
When MyClass gets more dependencies because we need logging and also need to notify a web service (please excuse the cliche examples), then it's really helpful to easily see what methods have which dependencies.
Tools like R# lets you extract a class from a set of private static methods in a few keystrokes. Try doing it when all private helper methods are tightly coupled to the instance field and you'll see it can be quite a headache.
As has already been stated, there are many advantages to static methods. However; keep in mind that they will live on the heap for the life of the application. I recently spent a day tracking down a memory leak in a Windows Service... the leak was caused by private static methods inside a class that implemented IDisposable and was consistently called from a using statement. Each time this class was created, memory was reserved on the heap for the static methods within the class, unfortunately, when the class was disposed of, the memory for the static methods was not released. This caused the memory footprint of this service to consume the available memory of the server within a couple of days with predictable results.