Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Queue questions

Tags:

c#

.net

In our application we have a Queue which is defined as the following:

private static Queue RawQ = new Queue();

Then two different types of objects are put onto the Queue, one are objects from a class (class A) and one are objects from a struct (struct B).

When we process the data from the Queue, we use typeof to check the item from the Queue belongs to which type (class A or struct B).

My questions:

  1. for objects from class A, only their references are copied to the Queue and for object from struct B, their values are copied to the Queue, am I right?
  2. for a Queue, some items are references which is small and some items are values which are much bigger (about 408 Bytes). This will waste many memory space if the Queue is not small?
  3. do you have a better way to do the same thing?

thanks,

like image 599
5YrsLaterDBA Avatar asked Feb 27 '23 14:02

5YrsLaterDBA


2 Answers

for objects from class A, only their references are copied to the Queue and for object from struct B, their values are copied to the Queue, am I right?

Correct. Actually, when you add a struct B to the queue, it is boxed first. In other words, your B instance is copied onto the managed heap, and a reference to the copy is put on the queue.

for a Queue, some items are references which is small and some items are values which are much bigger (about 408 Bytes). This will waste many memory space if the Queue is not small?

Possibly - boxing the B instance takes a copy, which uses more memory than not taking a copy. It depends what happens to the original.

408 bytes is very large for a .NET struct; the general rule of thumb is that structs shouldn't be bigger than 16 bytes. The reason is similar to this: large structs introduce overhead due to copying and boxing.

do you have a better way to do the same thing?

I'd question whether B needs to be a struct in the first place. Another rule of thumb (mine, this time): you probably don't need ever need a struct in .NET code.

like image 173
Tim Robinson Avatar answered Mar 07 '23 08:03

Tim Robinson


1.for objects from class A, only their references are copied to the Queue and for object from struct B, their values are copied to the Queue, am I right?

That is correct. Except that value types would be boxed.

2.for a Queue, some items are references which is small and some items are values which are much bigger (about 408 Bytes). This will waste many memory space if the Queue is not small?

That is mostly correct. The boxing will add another 8 bytes (4 for the syncblock and 4 for the type information) so for large structs that is insignificant, but for smaller structs that would represent a larger ratio.

3.do you have a better way to do the same thing?

The best thing to do is convert that large struct into a class. There is no hard rule for knowing when to choose a struct or class based on size, but 32 bytes seems to be a common threshold. Of course, you could easily justify larger structs based on whether you really wanted value-type semantics, but 408 bytes is probably way beyond that threshold. If the type really needs value semantics you could make it an immutable class.

Another change you could make is to use the generic Queue class instead. Value types are not boxed as they would be with the normal Queue. However, you would still be copying that large struct even with the generic version.

like image 27
Brian Gideon Avatar answered Mar 07 '23 08:03

Brian Gideon