Memory consuption: is better a static variable or not? - c#

I'm building a dll that have a Singleton pattern, so essentially the user add my dll, import the reference and execute a method like so:
FooClass.Foo();
now suppose that this method return a list each time, and have this structure:
static class FooClass
{
private static List<string> _fooList = new List<string>();
public static List<string> Foo()
{
_fooList.Clear();
//list population
return _fooList;
}
}
how you can see in the method Foo I clear each time the list instead of creating new instance of that list I reuse the object.
My question at this point is:
Is better create a new istance of the list inside the method Foo, or use the same list object as in my example?
All the result returned will be saved in another object by the user, so I don't need to keep the list in memory.
Any tips would be appreciated! Thanks.

Is better create a new instance of the list inside the method Foo, or use the same list object as in my example?
The two approaches are not equivalent, because clear modifies the instance that may be in use by some other part of your program. This may lead to significant problems, especially in concurrent environments. Given that the result returned will be saved in another object by the user, the problems are virtually guaranteed in your case if you use clear.
I don't need to keep the list in memory.
Then remove the static _fooList, and simply create a new object each time the method is called. Clearing the singleton on every single call defeats the purpose of having a singleton in the first place.

Related

Am I missing some benefits of static fields? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am working through C# in a Nutshell from Joseph Albahari & Ben Albahari which has been a great book by the way and am reading through the topic on static fields in C#. They have this example code,
public class Panda
{
public string name;
public static int population;
public Panda(string n)
{
name = n;
population = population + 1;
}
}
So I understand that the more instances of Panda that you instantiate the greater population will be become since it is shared amongst all objects of type Panda but now to my question.
Why? I just can't understand why I would ever want to utilize such behavior in an application. It seems like a confusing way to track a global variable within the object itself. Am I misunderstanding the potential benefits of a static field? What are some cases where this would be useful and not confusing?
I think it's best to review what happens under the hood first.
If you create a static class, a single instance is created at runtime. It happens whenever you try to use the type the first time and is used from there on. This can come in handy if you want to, say, lazy load a shared resource for instance. It also guarantees (via compiler and runtime) that you have one and only one instance at all times.
If the class is not static but you use static members, you can construct new instances, but a "static version" is maintained for you in the background. This is useful for situations in which you need to either keep track of something or if you want to share something across instances or even other code if you make the member public.
In terms of performance for instance, it could be really useful if you need to speed up your program and realize (through object count) that you are instantiating an object that never changes 100 times. Maybe you want to show your user how many Pandas have been born. You could in theory keep a count somewhere else but if you think about it, you will need another object anyways so it makes sense to keep all related information and logic together. Besides, you could have a more general type that breaks into derived ones and you may want to track all of them without having to keep adding logic.
Consider the following example:
public abstract class Animal
{
private static int _count;
protected Animal()
{
IncrementCount();
}
protected static void IncrementCount()
{
_count++;
}
public int WorldPopulation()
{
return _count;
}
}
public class Dog : Animal
{
}
public class Cat : Animal
{
}
public class Bird : Animal
{
}
If I was to create a Dog, Cat and Bird instance and then check the value of the WorldPopulation() method, I would get 3.
The Singleton pattern is also commonly implemented using this approach. It allows you to maintain a single instance while containing the construction internally:
public class SingletonSample
{
private SingletonSample()
{
}
private static SingletonSample _instance;
public static SingletonSample Instance
{
get
{
if(_instance == null)
_instance = new SingletonSample();
return _instance;
}
}
public bool IsThisTrue()
{
return true;
}
}
Notice you can't access the IsThisTrue() method via Class name, you need an instance and it cannot be created directly. It can only be created internally by the class itself:
//Object construction occurs the first time you access the "Instance" property
SingletonSample.Instance.IsThisTrue();
I hope that helps.
I just can't understand why I would ever want to utilize such
behavior in an application.
You'd never want to know the panda-count in a game? What about high-score?
Now, whether static fields are the best approach is a different manner - there are alternative patterns, but they tend to be far more complex to build and manage.
Short answer:
Consider that a cache is a place to store the result of computation. Caches are useful whenever the computation is expensive, but the storage is cheap. In C#, a static variable is just a cache for computations about a live system.
Longer answer:
Theoretically, we could discover anything that we wanted to know about a running system by searching for all objects, and then performing a computation with respect to some subset. Since this is exactly what the garbage collector does, a hypothetical CLI that provided the right hooks into the garbage collector would obviate the need for static variables.
For example, suppose we wanted to know how many Widget objects that we’ve created. Well, all we would need to do is ask the GC for a list of all of the live objects, then filter the list for objects of type Widget, and then count the Widgets.
But there are a couple of problems in the example: Firstly, some of the Widget objects might not be live (not reachable, thus not able to undergo state changes), but we would need to keep them around just for counting purposes. Even if the size of each Widget instance was only a single bit, we would still need 122KB of memory if we needed to keep a count of, say, one million Widgets (since a CLR object is at least 4 bytes, we would need almost 4MB just to keep track of the count). On the other hand, a 20-bit variable is enough to count up one million. This is a savings of 99.99% (actually 99.99999% in the case of the actual CLR). Secondly, garbage collection can be an expensive operation. Even if we avoid the overhead of memory compaction, we would just need to pause the system in general.
So, hopefully, it’s now easy to see why we would want to have the ability to cache certain computations about a live system, and hence the usefulness of static variables.
Having said all that, it is often the case that it's better to just recompute things rather than caching the results in a static variables because of the way CPU caching works.
here is an example of how i used static objects.
I had task to create an uploader handler with progress bar.
and progress bar had show up to all users that are in the site.
so a created the upload operation in a new thread and then appended the result of the operation to a static object(Progress bar) that are outside the thread, the progress bar will show up to all users that are viewing the site.
more info and exemplar could be found here
What is the use of static variable in C#? When to use it? Why can't I declare the static variable inside method?

Instantiating various inherited classes through one method, without reflection

In a project I'm working on, I have a set of blocks that make up a 3D voxel based environment (like Minecraft). These worlds are stored in an external data file.
This file contains the data for:
Each block,
its location,
and its type.
When the LoadLevel method is called, I want it to iterate over the data for every block in the file, creating a new instance of the Block object for every one. It's no problem to pass things like location. It's as simple as
CreateBlock(Vector3 position)
The issue is with the type. All types are child classes (think Abstract Block, and then subtypes like GrassBlock or WaterBlock that inherit the abstract Block's properties.) Assuming there's a child class like "GrassBlock" that I want to be created, rather than a generic block, how do I make it do this through the method? The only way I know of is through reflection, which I've been advised to stay away from. Is it possible that I can do this through generic typing or something?
This seems like such an important question in game design, but no one I've asked seems to have any idea. Any help?
Generic typing will still require reflection.
First of all: what you're looking for is the factory pattern. It creates objects for you without having to do it explicitly yourself everywhere.
Basically there are two options:
Reflection
This indeed has a performance impact connected to it but don't dismiss it if you haven't determined it to be a problem yet. It will be readable and maintainable.
Switches
Hardcode every option and create a new instance based on some sort of metadata you pass in (something that will identify the type of each block). This has the benefit of not using reflection and as such not incurring that performance penalty but it will also be less extensible and if you have 500 different blocks you can guess what your code will look like.
Of course, you can create objects without any reflection.
Simple assign each class the integer index:
Func<Vector3, Block>[] factories =
{
(v) => new GrassBlock(v), // index 0
(v) => new WaterBlock(v), // index 1
. . .
}
Save this index in the external data. At deserialization time read Vector3 v and index i, then call var block = factories[i](v);
Without reflection, you can use a factory method, with a switch. Assume BlockType is an enum.
public static Block CreateBlock(BlockType type, Vector3 position)
{
switch (BlockType type)
{
case BlockType.Grass:
return new GrassBlock(position);
case BlockType.Water:
return new WaterBlock(position);
default:
throw new InvalidOperationException();
}
}
But to have something more maintainable, you could still use reflection until it proves to be a bottleneck. In that case, you could switch to runtime code generation.
private static readonly Dictionary<Type, Func<Vector3, Block>> _activators = new Dictionary<Type, Func<Vector3, Block>>();
public static Block CreateBlock(Type blockType, Vector3 position)
{
Func<Vector3, Block> factory;
if (!_activators.TryGetValue(blockType, out factory))
{
if (!typeof(Block).IsAssignableFrom(blockType))
throw new ArgumentException();
var posParam = Expression.Parameter(typeof(Vector3));
factory = Expression.Lambda<Func<Vector3, Block>>(
Expression.New(
blockType.GetConstructor(new[] { typeof(Vector3) }),
new[] { posParam }
),
posParam
).Compile();
_activators.Add(blockType, factory);
}
return factory(position);
}
This code will generate a factory function at runtime, the first time a block of a given type is requested. And you could make this function thread-safe if needed by using a ConcurrentDictionary.
But that may be a bit overkill for your purpose ;)
Why are you avoiding reflection? If you're able to execute this code only on startup (which it sounds like you can do if you're reading a file) then I don't personally have too big a problem with using reflection.
An alternative is to store the fully qualified type name (e.g. My.System.Blocks.GrassBlock) and load that type with
var typeName = readStringTypeFromFile(file);
Block type = Activator.CreateInstance(typeName, location);
As I said, running something like this on startup is fine by me, and you can test performance of this if needs be.
Quick and dirty fiddle: https://dotnetfiddle.net/BDmlyi

Function should get called only once

I have one c# function which returns me List of States. I want this function should get called only once like static variable.
public List GetStateList()
{
List lstState=new List();
lstState.add("State1");
lstState.add("State2");
lstState.add("State3");
return lstState;
}
I m calling this function from many places since this state list is going to be same so i want this function should get called only once, and next time when this function is getting called it should not re create the whole list again.
How could i achieve this in c#.
Memoise it. It'll still be called multiple times, but only do the full work once:
private List<string> _states; //if GetStateList() doesn't depend on object
//state, then this can be static.
public List GetStateList()
{
if(_states == null)
{
List lstState=new List();
lstState.add("State1");
lstState.add("State2");
lstState.add("State3");
_states = lstState;
}
return _states;
}
Depending on threading issues, you may wish to either:
Lock on the whole thing. Guaranteed single execution.
Lock on the assignment to _states. There may be some needless work in the early period, but all callers will receive the same object.
Allow for early callers to overwrite each other.
While the last may seem the most wasteful, it can be the best in the long run, as after the initial period where different calls may needlessly overwrite each other, it becomes a simpler and faster from that point on. It really depends on just how much work is done, and how often it may be concurrently called prior to _states being assigned to.
One issue with reusing a list is that callers can modify this list, which will affect any pre-existing references to it. For such a small amount of data, this isn't likely to save you very much in the long run. I'd probably be content to just return a new array each time.
I certainly wouldn't bother with lazy instantiation; populate it in the constructor and be done:
public static class States {
static States() {
All = Array.AsReadOnly(new string[] { "state1", "state2", "state3" });
}
public static readonly ReadOnlyCollection<string> All;
}
Now it's thread-safe, (relatively) tamper-proof, and above all, simple.

Static values vs passing parameters

I have a situation where I have to pass a List<> across 2-3 independent classes up and down the class. Right now I'm mostly passing the list using parameter so all 3 classes gets the list. Should I use a static list instead of passing List all over the classes to simplify the code like Class23.ListObjects.Add() and then release the static values once the operation is done so the next operation starts with an empty List. Right now it feels like the parameters are getting a lot and I'm getting confused if the list has the right values, forgetting to pass the list to the next class, etc. What do you think?
I would suggest you create a new class that represents the combined operation performed by the various classes (a "context" class, if you will). Values needed to perform the operation can be held as instance variables in that context, along with instances of the classes used in performing the work.
That way, you avoid passing stuff around (as code evolves, this can get somewhat ugly) while avoiding a "global" variable. Data is in exactly the scope it needs to be, and is disposed when the overall operation is complete.
In Coding practices, it is bad to have static or Global variables and passing through parameters is considered good.
If you use a static parameter, you run the risk of getting corrupted data if those functions are used in multiple places in your code, especially if threading is involved.
For instance, suppose Class A needs to use your functions that act on your static list. Before those functions are completed, Class B tries to use them as well, causing the list to get data from both calls, since the same static list is used in both cases.

Looking for advice on thread safety using static methods to 'process' a class instance

I have recently inherited a system that uses a very basic approach to processing workitems, basically, it does them one by one. To be honest, up until recently this worked well. However, we are looking to implement a similiar process for another type of workitem and I have been looking into Task Parallel Library and think that will fit the bill. However, I have some concerns about Thread Safety and to be honest, this is an area that I lack knowledge, so I am asking only my 2nd question on here in hope that someone can give me some good points as I have yet to find a definitive yes or no answer for this.
So we have our 'WorkItem' class
public class WorkItem
{
public int Id {get; set;}
public string data { get; set;}
}
A List<WorkItem> will be generated and these will then be processed using a Parallel.Foreach loop.
The Parallel.Foreach will call a private method, which in turn will call static methods from another assembly;
//Windows service that will run the Parallel.Foreach
private int MainMethod(WorkItem item)
{
item.Data = Processor.ProcessWorkItemDataProcess1(item.data);
item.Data = Processor.ProcessWorkItemDataProcess2(item.data);
SendToWorkFlow(item);
}
public static class Processor
{
public static string ProcessWorkItemDataProcess1(string data)
{
//Process it here
return string
}
public static string ProcessWorkItemDataProcess2(string data)
{
//Process it here
return string
}
}
And so on. All of these methods have logic in them to process the WorkItem instance at various different stages. Once complete, the MainMethod will send the processed WorkItem off to a Workflow System.
We will be processing these in batches of up to 30 in order not to overload the other systems. My concerns are basically the potential of 30 instances of WorkItem accessing the same static methods could cause some data integrity issues. For example, ProcessWorkItemDataProcess2 is called with WorkItem1.Data and is subsequently called with WorkItem2.Data and somehow WorkItem2.Data is returned when it should be WorkItem1.Data
All of the static methods are self-contained in so far as they have defined logic and will only (in theory) use the WorkItem that it was called with. There are no methods such as DB access, file access, etc.
So, hopefully that explains what I am doing. Should I have any concerns? If so, will creating an instance of the Processor class for each WorkItem solve any potential problems?
Thanks in advance
The scenario you describe doesn't sound like it has any blatant threading issues. Your worries about a static method being called on two different threads and getting the data mixed up is unfounded, unless you write code to mix things up. ;>
Since the methods are static, they don't have any shared object instance to worry about. That's good. You have isolated the work into self-contained work items. That is good.
You will need to check to make sure that none of the static methods access any global state, like static variables or properties, or reading from a file (the same file name for multiple work items). Reading of global state is less of a concern, writing is what will throw a wrench in the works.
You should also review your code to see how data is assigned to your work items and whether any of the code that processes the work items modifies the work item data. If the work items are treated as strictly read only by the methods, that's good. If the methods write changes back to fields or properties of the work items, you will need to double check that the data in the work items is not shared with any other work items. If the code that constructs the work item instances assigns a cached value to a property of multiple work items, and the static methods modify properties of that value, you will have threading conflicts. If the work item construction always constructs new instances of values that are assigned to properties of the work item, this shouldn't be an issue.
In a nutshell, if you have multiple threads accessing shared state, and at least one is writing, then you need to worry about thread safety. If not then you're golden.

Categories

Resources