tags:

views:

91

answers:

4

For performance reasons I use structs in several use cases.

If I have an object or a nullable type (another struct but nullable) as a member in the struct, is there an adverse effect on performance. Do I lose the very benefit I am trying to gain?

Edit

I am aware of the size limitations and proper use of structs. Please no more lectures. In performance tests the structs perform faster.

I do not mean to sound abrasive or ungrateful, but how do I make my question any more simple?

Does having a object as a member of a struct impact performance or negate the benefit?

+2  A: 

No, you won't lose the benefit necessarily. One area in which you see a performance benefit from using a struct is when you are creating many objects quickly in a loop and do not need to pass these objects to any other methods. In this case you should be fine but without seeing some code it is impossible to tell.

Andrew Hare
You need to see code to answer the above question? Seriously???
Gary
Your question asks about the performance benefits of a struct yet you provide no example of how the struct is used. It is similar to you asking me how a particular car will perform without telling me where the car will be driven (city, highway, offroad, etc). I am simply requesting a simple code example to provide context for your question. *As a side note:* In the future, when asking others for assistance, it would be better to be more accommodating and less abrasive.
Andrew Hare
Let me explain, you have 41K worth of rep which makes you about 38% of Jon Skeet. I was simply surprised that you asked for a code sample. If maybe you only had say 20K I would have let you slide.
Gary
Trust me Gary, I may have 38% of Jon Skeet's reputation but that does not in any way imply that I posses anywhere close to 38% of his knowledge or intellect. I still don't understand how having a lot of Stack Overflow reputation would somehow imbue me with the ability to read your mind and extract your use cases to be able to tell you how your struct would perform for each of them.
Andrew Hare
+2  A: 

Personally, I'd be more worried about simply using structs inappropriately; what you have described sounds like an object (class) to me.

In particular, I'd worry about your struct being too big; when you pass a struct around (between variables, between methods, etc) it gets copied. If it is a big fat beast with lots of fields (some of which are themselves beasts) then this copy will take more space on the stack, and more CPU time. Contrast to passing a reference to an object, which takes a constant size / time (width per your x86/x64 architecture).


If we talk about basic nullable types, such as classic "values"; Nullable<T> of course has an overhead; the real questions are:

  • is it too much
  • is it more expensive than the check I'd still have to do for a "magic number" etc

In particular, all casts and operators on Nullable<T> get extra code - for example:

int? a = ..., b = ...;
int? c = a + b;

is really more similar to:

int? c = (a.HasValue && b.HasValue) ?
              new Nullable<int>(a.GetValueOrDefault() + b.GetValueOrDefault())
            : new Nullable<int>();

The only way to see if this is too much is going to be with your own local tests, with your own data. The fact that the data is on a struct in this case is largely moot; the numbers should broadly compare no matter where they are.

Marc Gravell
+2  A: 

Well, C# is a strange beast when it comes to the performance part of struct vs classes.

Check this link: http://msdn.microsoft.com/en-us/library/y23b5415%28VS.71%29.aspx

According to Microsoft you should use a struct only when the instance size is under 16 bytes. Andrew is right. If you do not pass around a struct, you might see a performance benefit. Value type semantics have a heavy performance (and at time memory, depending on what you are doing) penalty while passing them around.

As far as collections are concerned, if you are using a non-generic collection, the boxing and unboxing of a value-type (struct in this case) will have a higher performance overhead than a reference type (i.e. class). That said, it is also true that structs get allocated faster than classes.

Although struct and class have same syntax, the behavior is vastly different. This can force you to make many errors that might be difficult to trace. For example, like static constructors in a struct would not be called when you call it's public (hidden constructor) or as operator will fail with structs.

Nullable types are themselves are implemented with structs. But they do have a penalty. Even every operation of a Nullable type emit more IL.

Well, in my opinion, struct are well left to be used in types such as DateTime or Guids. If you need an immutable type, use struct otherwise, don't. The performance benefits are not that huge. Similarly even the overhead is not that huge. So at the end of day, it depends on your data you are storing in the struct and also how you are using it.

Yogesh
A: 

Nullable<T> is essentially a tuple of T and bool flag indicating whether it's null or not. Its performance effect is therefore exactly the same: in terms of size, you get that extra bool (plus whatever padding it deems required).

For references to reference types, there are no special implications. It's just whatever the size of an object reference is (which is usually sizeof(IntPtr), though I don't think there's a definite guarantee on that). Of course, GC would also have to trace through those references every now and then, but a reference inside a struct is not in any way special in that regard.

Pavel Minaev