C# best practice for performance: object creation vs reuse - c#

I am currently working on performance tuning of an existing C# website. There is a class say.. MyUtil.cs. This class has been extensively used across all web pages. On some pages around 10/12 instances are created (MyUtil). I ran the "Redgate" performance profiler. The object creation is a costly operation according to RedGate.
Please note that each instance sets specific properties and performs specific operation. So I can not reuse the object as it is. I have to reset all the member variables.
I want to optimize this code. I have thought about following options. Kindly help me evaluate which is the better approach here :
(1) Create a "Reset" method in "MyUtil.cs" class which will reset all the member variables (there are 167 of those :(..) so that I can reuse one single object in an page class.
(2) Continue with the multiple object creation (I do have Dispose() method in "MyUtil")
(3) I thought of "object pooling" but again I will have to reset the members. I think its better to pool objects at page level and release them instead of keeping them live at the project level.
Any reply on this will be appreciated. Thanks in advance..!

Every app has multiple opportunities for speedup of different sizes, like kinds of food on your plate.
Creating and initializing objects can typically be one of these, and can typically be a large one.
Whenever I see that object creation/initialization is taking a large fraction of time, I recycle used objects.
It's a basic technique, and it can make a big difference.
But I only do it if I know that it will save a healthy fraction of time.
Don't just do it on general principles.

I would recommend that you always create new objects instead of resetting the objects. This is so for the following reasons
GC is smart enough to classify objects and assign them a generation. It depends on the usage of objects in your code. Profiling is done based on the execution pattern of code as well as architecture of code
You will be able to get optimum result from hardware if you use the GC and let it manage the process as it also decides the garbage collection thresh hold based on hardware configuration available and available system resources.
Apart from that, your code will be much easier and manageable. - (Though it is not a direct benefit, but should also give at least some weight to it.)
Creating object pool at page level is also not a good idea because to re-use the object, you will have to do two things, fetch it from pool and reset its properties, i.e. you will also have to manage the pool which is additional burden
Creating a single instance and re-using it with resetting properties might also not be a good idea cause when you need more then one instance of object, it will not work.
so the conclusion is, you should keep creating objects in the page and let the Garbage collector do its job.

Related

How do I read a Visual Studio 2019 memory snapshot of my C# service usefully?

I've read the other questions that come up when I ask about memory snapshots, but I might be too thick to really grasp it. I have a windows service that I can produce a memory leak in by doing a pretty straightforward data operation repeatedly. I've taken memory snapshots along the way, and I see that the number of roots is going up (from 2,100 after a successful start to 7,100 after 100 or so data operations). The snapshots were taken at the blue arrow marks:
Before the multiple data operations, the memory snapshot looks like this:
Afterwards, it looks like this:
We're using WCF for data transport and it would appear that Serialization is playing a part in this memory growth, but I don't know where to go from here. If I look at instances of RuntimeType+RuntimeTypeCache, the vast majority of instances look like this:
If anyone can help me figure out the next step to take, I would appreciate it immensely. We have a static instance that has a concurrent dictionary of ServiceHosts that I'm suspicious of, but I don't know how to confirm it.
EDIT:
This also seems significant and is in reference to ServiceHosts. Could we be enabling some unwise proxy generation and instance retention via this static relationship?
Sort your items by Size, and inside that list, watch out for your own class types. Which one is piling up. Have at least a total of a few Megabytes of objects, to be sure to see a real 'Pile' not just some parts of the infrastructure.
The 12.000 existing runtime types, might indicate dynamically created types, maybe the serialization DLL is created for each new call.
You can also try to do GC.Collect() after your critical function call, to enforce Garbage collection.

C# - Performance of reusing object with string properties vs creating new instance

Suppose I have class A that contains 3 string properties. New instances of A are being created several times needlessly throughout the application. All class A does is use these 3 strings to perform a LINQ query like:
Where(string1 == this.string1).Where(string2 == this.string2).Where(string3 == this.string3)
Instead of creating an instance every single time the object is needed, I'm thinking about modifying the classes that use this type to store one instance of the object and then modify the string properties before using it each time. Is this the right way to optimize the class? Basically, I'm trying to avoid the overhead of creating the instance and allocating the memory for the strings every time.
Is there a faster way to perform the above LINQ query instead?
Yes it is. But unless there're plenty of those objects, the difference in performance will be negligible.
If "several times" is on the order of a few thousand then I wouldn't worry about the performance of creating the objects. Only if you are creating so many that the application is having to frequently perform a garbage collection to cleanup the unused objects, which for an object with 3 properties would need to be on the order of millions unless your strings are extremely large.
You are more likely to create bugs by trying to reuse an object, since you run the risk of forgetting to clean object state between reuses.
Trying to reuse the object will likely mean moving it to a higher level scope than necessary. I.e. changing a local reference to a property, or similar.
Keep your code simple, rather than implement premature optimizations, such that when you do get into a situation where optimization is really important, then you can more easily implement optimizations. If you over optimize everything you can imagine, then you will end up with an over complicated code base.
Update:
I'm thinking about modifying the classes that use this type to store
one instance of the object and then modify the string properties
before using it each time. Is this the right way to optimize the
class?
You're not saving much in the realm of memory allocation. Since you are assigning new strings each time, most of the allocation is in the creation of the strings, not in the creation of the object.
The outer object consists of little more than 3 pointers.
Whether you reuse the same object repeatedly, or not, the majority of memory allocation is the creation of strings each time.
If you are going to put effort into optimization, your efforts should be focused where they will be most beneficial. Efforts devoted to optimization should begin with profiling to determine where your slow points are. This means optimizing those things that have been measured to be problem areas.

c# Static or Non Static Class

I have a c# windows forms mp3 player application. I have the audio files in my Resources folder and a separate "MyAudio" static class which handles all the audio related work like playing and increasing volume etc.
From my Form, I just call the play method using:
MyAudio.Play(track);
In the MyAudio class, I have a WindowsMediaPlayer object declared as:
private static WindowsMediaPlayer obj=new WindowsMediaPlayer();
My Question is, in terms of efficiency and less memory usage, is it better to declare MyAudio class as static or non static? Is it wise to create a Object of the MyAudio class in form and then call the methods or directly call using class Name?
Also is it good practice to declare the instance variables as static?
Your question is indeed broad, but there are few design principles that you can take care of, while you are designing a class:
Do I need the object and it's state throughout the application lifetime
Do I need to maintain the state of class variables for future use
Do I need to multi-thread or parallelize the application at any point of time
Do I need to decouple the component in the future and used in other scenarios like Ajax based web scenario
Important thing in this case is that you are keen to maintain the state for the application lifetime and the amount of memory usage is fine for the application environment, since after initializing you would be able to get all the data from memory and don't need to query a source like database. However, this is good for the scenario where you need to initialize once and read as a static information in the rest of the application. In case you plan to re query the information, then the part purpose of using static type would be lost
Let's assume in the future you need to parallelize your code for performance enhancement, then static will come to haunt you, since it would be shared among threads and invariably would need a synchronization construct like lock, mutex, which will serialize all threads and thus purpose would be lost. Same things would happen in a Web / Ajax scenario and your static component cannot handle the multiple parallel requests and will get corrupted until and unless synchronized. Here instance variable per thread is a boon, as they do task / data parallelization without requiring a lock, mutex
In my understanding static is a convenience, which many programmers misuse, by avoiding the instance variable and using at will, without understanding the implications. From the GC perspective, it cannot collect the static variable, so the working set of the application would invariably increase till it stabilize and will not decrease until and unless explicitly released by program, which is not good for any application, until and unless we are storing data to avoid network database calls.
Ideal design would suggest to always use the instance class, which gets created, does its work and gets released, not linger around. In case there's information that needs to be passed from one function to another like in your case from Play to Pause to Stop, then that data can be persisted to a static variable and modified in a thread safe manner, which is a much better approach
If we just take example given by you since it's a windows form, which does operations like Play, then static would be fine, as it is an executable running on a system, but for testing imagine a scenario that you initiate multiple instances by double clicking and play around on each one, by pressing different operations, then they all will access same static object and you may get a corruption issue, in fact to resolve such scenario you may even chose your class to be singleton, where at a given moment no more than one instance can exist in the memory, like it happens for Yahoo messenger, no matter how many times you click, always same instance comes up.
There are no static instance variables. However its best practice to define static members if they don't have anything to do with a particular instance of the class.

Optimizing collection of long lived objects

Background:
I have a service whose purpose in life is to provide objects to requestors - it basically gets complicated data from a database and transforms it once (a bit like a view over data) to produce a simplified record. This then services requests from other services by providing up to 100k records (depending on the nature of the request) on demand.
The idea is that the complicated transformation is done once and is cached by the service - it works out quicker than letting the database work it out each time a view is accessed and for my purposes works just fine. (I believe this is called SSOS by some)
The way data is being cached is in a list of objects which are property bags for standard .Net types. These objects have no references to anything else.
Periodically a record will change, and the cache must be updated which means that the original record must be located, thrown away and replaced.
Now the record in the cache will have been in there for a long time and will have been marked for a Gen 2 collection; pretty much all the collections will happen in the Gen2 phase as these objects are hanging around for ages (on purpose).
So my understanding of Gen2 collections is that they are slow, and if the collections are mainly working on Gen2 then the optimizer is going to do this more often.
I would like to be able to de-reference an object in the list in a way that doesn't end up triggering a full Gen2 collection... I was thinking that maybe there is a way of marking it as Gen0 and then de-referencing it before replacing it - but I don't think that is possible.
I am constrained to using .Net 4 for this and the application is a service which serves data to up to 100 clients who request full lists or changes to the list over a period of time.
Question: Can anyone suggest a way to de-reference long lived objects in a GC friendly way or perhaps another way to approach this problem?
There is no simple answer to this. If you have lots of long-lived objects, then full collections really can hurt, as I discussed here. Since a picture tells a thousand words:
Those vertical spikes are where garbage collection happens and slaughters the response times.
The way we reduced the impact of this was: don't have a gazillion long-lived objects. What we did was to change the classes to structs, which meant that the only object was the array that contained them. We were fortunate here is that the data was simple and didn't involve strings, which would of course themselves be objects. We also did some crazy fixed-size buffer work to reduce things that were previously collections, and changed what were references to indices (into the array). If you do have to use string data, perhaps try to ensure you don't have 20,000 different string instancs with the same value - some kind of manual interner (a Dictionary<string,string> would suffice) can be really useful there.
Note that this needn't impact your public API, since you can always create the old class data from the struct storage - the difference is that this class will only exist briefly as a DTO - so will be collected cheaply in the next gen-0 sweep.
YMMV, but this worked enough well for us.
The problem is: you need to be really careful when working with structs; I strongly advise making them immutable.

.Net Memory Management Issue : Objects Stuck in Generation 2

I have profiled my App w/ VS2010 profiler, with object lifetime collection enabled.
I was heavilly surprised to see that most instances of a particular struct named "Record" are collected by the GC as Gen 2 instances. I am very upset, as instances of "Record" struct should live less than 500ms each (theoretically).
These structs are simple time series data of 6xInt32 or so, that are read on the flow, Queued/Dequeued in a Queue having a size of 1000, passed to a processor that fires some logic depending on those few millions "Records" sequentially. I do not need to keep more than 50 records at a time.
So my question is : Why could these object live long enough to mainly end up as Second Generation references, and what could I do to ensure they REALLY get dumped off after each computation.
EDIT :
I am asking this because I have noticed a drastic performance dropdown for bigger sample sizes (i.e Records Numbers) : if N take T minutes, 2N takes 2,5T minutes or so, and so on. So there is obviously a leak somewhere.
EDIT 2 :
My Bad : Creating a struct instance cannot cause a garbage collection
I've changed it to classes and did not notice any significant improvement so far.
I'll run the profiler again with classes this time not structs) and see what it gives
EDIT 3 :
Many answers suspect Boxing/Unboxing to take place somewhere.
I DO use typed generic collections and typed Queues. And "Records" are never attached to any class as members. They are individually handled by events.
The ex-Struct (Now Class) implemented an interface and was casted by it when called (this is rather common usage) and I dropped off that interface. No improvement.
EDIT 4 :
I have run again the profiler, replacing struct by class. I have the same results : most instances of CLASS "Record" still end up being collected as Gen2 instances
EDIT 5 :
Producers of the Record classes are many parallel BackGroundWorkers (Byte Readers), and there is one Consumer Thread that dispatches the Records to other methods after performing a few checks. Besides I use Events and Delegates to communicate between the different parts. I do not unregister those events because they are useful all along the process (I may be wrong on that point)
If you stored them just as local variables (which may or may not be possible depending on your scenario) they will never end up on the heap at all.
If that's possible, I recommend trying that. You might get a more in depth response, if you post a code sample.
As a sanity check, are you forgetting to unregister static events, or using some other class that may be doing this (some classes fix this via Dispose)?
Also have you looked into the possibility of using the Flyweight pattern?
Edit- Since you now say you are doing something with events, this is highly likely to be a cause of your issues. Are you forgetting to unregister the events?
If you are "heavy" on memory use, and you are using C# 4.0, you could try the "server" GC. Merge your app.config (or web.config) with:
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
(with merge I mean that if you already have some of these sections, use them, otherwhise create them. "configuration" is the first level element of the app.config). This is better for some apps (apps that don't need heavy interaction with the user)
They end up as Second Generation because the GC just decided not to garbage collect them. I don't think it is really a problem to worry about. If you really wanted to you could just reuse the 1000 objects instead of continuously creating new ones. This would make it so that these objects wouldn't need to get garbage collected. You could force Garbage collection to ensure the objects "REALLY" get dumped but that would degrade performance as GC is an expensive operation or so I am told.

Categories