C# static class - calculate the size - .net-4.0

Suppose I have a C# static class. It contains only only static methods. How do I calcute the size of it? What does affect its size in the memory?
And how much would it weigh if I included static fields?

You'll never be creating any instances of it, so the size is pretty much irrelevant.
Obviously as you add more methods they will take some memory (the IL, the JIT-compiled native code etc) but no more so than anywhere else - and almost certainly not significantly within your app.
If you add some static fields, again those take up memory - but they're only associated with the type, rather than any instances of the type. So if you add (say) a static field of type long, that will take an extra 8 bytes per AppDomain you load the type into. Insignificant in the grand scheme of things.

Related

Whether to put method code in a VB.Net data storage class, or put it in a separate class?

TLDR summary: (a) Should I include (lengthy) method code in classes which may spawn multiple objects at runtime, (b) does doing so cause memory usage bloat, (c) if so should I "outsource" the code to a class that is loaded only once and have the class methods call that, or alternatively (d) does the code get loaded only once with the object definition anyway and I'm worrying about nothing?
........
I don't know whether there's a good answer to this but if there is I haven't found it yet by searching in the usual places.
In my VB.Net (2010 if it matters) WinForms project I have about a dozen or so class objects in an object model. Some of these are pretty simple and do little more than act as data storage repositories. The ones further up the object model, however, have an increasing number of methods. There can be a significant number of higher level objects in use though the exact number will be runtime dependent so I can't be more precise than that.
As I was writing the method code for one of the top level ones I noticed that it was starting to get quite lengthy.
Memory optimisation is something of a lost art given how much memory the average PC has these days but I don't want to make my application a resource hog. So my questions for anyone who knows .Net way better than I do (of which there will be many) are:
Is the code loaded into memory with each instance of the class that's created?
Alternatively is it loaded only once with the definition of the class, and all derived objects just refer to that definition? (I'm not really sure how that could be possible given that, for example, event handlers can be assigned dynamically, but no harm asking.)
If the answer to the first one is yes, would it be more efficient to write the code in a "utility" object which is loaded only once and called from the real class' methods?
Any thoughts appreciated.
Go with whichever is going to be the easier to maintain codebase (shorter methods, etc). That is the more important cost with anything that has increasing complexity.
Memory optimization is only a problem if its a problem. 12 classes is really nothing, when you have hundreds of instances of hundreds of classes, then it may become a problem.
The short answer, it doesn't matter. Your data is stored in memory but your code is loaded only once.
EDIT: I guess I need a longer answer.
If you have 10 instances of a class, the variables that are part of that instance all take up thier own memory space. So if you have 10 properties, variables, etc, that means you have 100(ish) items in your memory. As for your code, it was loaded just once with your assembly. If you create 10 instances of your class, your code is not in memory 10 times.

Could it be beneficial to lazy instantiate members of a static class?

So, I have a class with members whom I am using more or less as constants. I cannot assign them as constants since they are more complex than a simple primitive. Therefore, these 'quasi-constants' are used repeatedly in various places in my application. Admittedly, I will likely move these to a configuration file in the future and have them loaded dynamically.
However, for now I was curious - that though these are served from a static class, could I at all benefit from wrapping them with lazy instantiation? The reason that I ask is because I do not make use of every 'quasi-constant' and there is some overhead associated with constructing each one (albeit very little). I do not expect any real gain by doing this, as it's not a bottleneck or anything, but I am curious as to best practices. I do not know enough about the internals of static classes to answer this myself. I do know that accessing static members does not require an instance of the class - though at some point it must be constructing those members. So my question boils down to this: when are static members of a static class constructed? If they are constructed prior to use, then could I at all benefit by lazy instantiation? (instantiating them only when they are requested?)
when are static members of a static class constructed?
The static constructor and all initialization occurs before the first instance of that class is created or any static members are referenced.
Typically, the static constructor and all static members are initialized immediately before the first time you refer to the class, though technically it can happen at any point prior to the first usage.
If they are constructed prior to use, then could I at all benefit by lazy instantiation? (instantiating them only when they are requested?)
You may benefit from this, particularly if the values require significant initialization or large memory usage, and may not always be used. The Lazy(Of T) class makes this fairly simple to implement.

Length ( number of methods ) of a class code and performance

What kind of dependency is between number of methods, or length of source code of a class to performance (memory usage, speed of execution )? It is better to create as simple class as possible, or I can implement as may function as I want to one class? Does Java load whole class to memory, when object is accessed by interfaces?
You're thinking about it for the completely wrong reason.
Forget about performance. It does not matter in this question. At all.
Huge classes are very bad because they are hard to maintain. They're hard to understand, probably violate the Single Responsibility Principle massively or even harbor duplicated code.
There are a lot of parts to your question but performance and class size usually shouldn't be talked about together. Make small classes because it's easier to maintain and debug.
Classes (class code) are loaded into memory when they are referenced for the first time, or maybe sooner depending on the class loader but this is usually a small price compared to actually executing your code.
Yes, Java loads the whole class into memory. But it's probably not the class that consumes most memory, but rather the number of instances of it.
I'd say that except for extreme cases, there is little or no correlation between the lengthes and number of methods in your classes and memory usage in runtine.
AFAIU, the number of methods in a class (or more accurately the size of the class) will only affect the loading time.

VB.NET: is using Structures considered nasty?

I use to use Structures quite a lot in the VB6 days, and try to avoid them now with .NET. Just wondering if using structures in 2010 instead of a Class is considered nasty?
Thanks for the help.
Choosing a Structure takes consideration instead of being inherently "nasty". There are reasons why a Structure can be nasty; however there are also reasons a Class can be nasty in its own way...
Basically when you decide between these two object oriented kinds of containers, you're deciding how memory will be used.
There are different semantics associated with Structure and Class in VB.NET and they represent different memory usage patterns.
By creating a Class you're creating a reference type.
good for large data
memory contains a reference to the object location on the heap (like the concept of pointing to an object) though happens transparently to the VB.NET programmer because you're in "managed mode".
By creating a Structure you're creating a value type.
good for small data
memory allocated contains the actual value
be judicious because these are apt to get pushed on the stack area of memory (i.e. for local vars, but not class fields) - too large and you could run into stack issues.
Also some good video resources on YouTube if you're an audio learner.
Many articles on the Internet like these MSDN articles to teach the basics and details:
Value Types and Reference Types
7.1 Types - Reference and Value
MSDN Type Fundamentals - subheading: Reference and Value Types
Example
Structures exist because in some scenarios they make more sense than classes. They are particular useful for representing small abstract data types such as 3D points, latitude-longitude, rational numbers, etc.
The basic motivation for using structs is to avoid GC pressure. Since structs live inline (on the stack or inside whatever container you put them in) rather than on the heap, they typically result in far fewer small allocations, which makes a huge difference if you need to hold an array of one million points or rationals.
A key issue to watch out for is that structs are value types, and thus are generally passed around by value (the obvious exception being ref and out parameters). This has important implications. For instance:
Point3D[] points = ...;
points[9].Move(0, 0, 5);
The above code works fine, and increases the z coordinate of the 10th point by 5. The following code, however:
List<Point3D> points = ...;
points[9].Move(0, 0, 5);
Will still compile and run, but you will find that the z coordinate of the 10th point remains unchanged. This is because the List's index operator returns a copy of the point, and it is the copy that you are calling Move on.
The solution is quite simple. Always make structs immutable by marking all fields readonly. If you still need to Move points around, define + on the Point3D type and use assignment:
points[9] = points[9] + new Point3D(0, 0, 5);
It's considered pretty bad to use anything without understanding the implications.
Structures are value types, not reference types - and as such, they behave slightly differently. When you pass a value type, modifications are on a copy, not on the original. When you assign a value type to an object reference (say, in a non-generic list), boxing occurs. Make sure you read up on the full effect of choosing one over the other.
Read this for some understanding benefits of structures vs classes and vice-versa.
A structure can be preferable when:
You have a small amount of data and simply want the equivalent of the UDT
(user-defined type) of previous versions of Visual Basic
You perform a large number of operations on each instance and would incur
performance degradation with heap management
You have no need to inherit the structure or to specialize
functionality among its instances
You do not box and unbox the structure
You are passing blittable data across a managed/unmanaged boundary
A class is preferable when:
You need to use inheritance and polymorphism
You need to initialize one or more members at creation time
You need to supply an unparameterized constructor
You need unlimited event handling support
To answer your question directly, there is nothing inherantly wrong with using a structure in VB.NET. As with any design decision you do need to consider the consequences of this decision.
It's important that you're aware of the difference between a class and a structure so that you can make an educated decision about which is appropriate. As stated by Alex et al, one of the key differences between a structure and a class is that a structure is considered a value type and a class is considered a reference type.
Reference types use copy-by-reference sematics, this means that when an object is created or copied, only a pointer to the actual object is allocated on the stack, the actual object data is allocated on the heap.
In contrast, value types have copy-by-value sematics which means that each time a value type (e.g. a structure) is copied, then the entire object is copied to a new location on the stack/
For objects with a small amount of data, this isn't really a problem, but if you have a large amount of data then using a reference type will likely be less expensive in terms of stack allocations because only a pointer will be copied to the stack.
Microsoft have guidelines on the use of structures that more precisely describe the differences between classes and structures and the consequences of choosing one over the other
From a behavioral standpoints, there are three types of 'things' in .net:
Mutable reference types
Value types which can be mutated without being entirely replaced
Immutable reference and value types
Eric Lippert really dislikes group #2 above, since .net isn't terribly good at handling them, and sometimes treats them as though they're in group #1 or #3. Nonetheless, there are times when mutable value types make more sense semantically than would anything else.
Suppose, for example, that one has a rectangle and one wants to make another rectangle which is like the first one, but twice as tall. It is IMHO cleaner to say:
Rect2 = Rect1 ' Makes a new Rectangle that's just like Rect1
Rect2.Height = Rect2.Height*2
than to say either
Rect2 = Rect1.Clone ' Would be necessary if Rect1 were a class
Rect2.Height = Rect2.Height*2
or
Rect2 = New Rectangle(Rect1.Left, Rect1.Top, Rect1.Width, Rect1.Height*2)
When using classes, if one wants an object that's slightly different from an existing object, one must consider before mutating the object whether anyone else might want to use the original; if so, one must make a copy of it and then make the desired changes to the copy. With structs, there's no such restriction.
A simple way to think of value types is to regard every assignment operation as making a clone of the original, but in a way that's considerably cheaper than cloning a class type. If one would end up cloning a lot of objects as often as one would assign references without cloning, that's a substantial argument in favor of structs.

Do "heavy" properties carry weight, even if they are not populated?

Let's say you havew a user class. When the user is logged in there are properties representing basic user info, an associated address and, say, 5 profile pictures, the last a generic lsit like this: Private _photos As List(Of Photo). However, instead of carrying the weight of the profile pictures in a session vairable, to reduce resource usage, I only want to populate them if the user needs to acces them. So, for the most part, the generic list of photo's is empty. Will it carry weight anyway? I'm trying to decide if I should just not populate ituntil needed, or if I should create an alternative "light" user class which doesn't have this property.
Provided the "heavy" properties are using a referenced type that will be allocated on the heap, and the allocation is not made until they are needed, they will have very little overhead. In most languages, the overhead will be platform specific, and usually equal to the size of a memory address (ie: a single pointer length, typically 32bit or 64bit per property).
For example, it looks like you're using VB.NET. The List(Of T)'s overhead will be minimal until you start adding elements to it. Then, you take the hit for each element. The List will allocate some initial buffer of pointers, so you'll get a pointer for the list (32/64bit), and an array to hold pointers, but none filled in. In general, you're not talking about a large amount of memory.
If, however, the properties are a value type (this depends on language a bit), they may get allocated in your class directly. This can cause them to have a high overhead in all cases. This is unlikely to be the case, though, since having "heavy" objects as value/stack allocated types is a bad design to begin with.
Assuming you are storing the paths in a RDB, the roundtrip time for requesting properties on demand are likely to be larger than just requesting them every time. However, you need to look at your usage: Will it be 9 of 10 times they need the path or 1 / 10?
Try it out both ways in a miniproject and then profile it. This is one of those times where there is no "right" answer.