Struct vs. Class

G

Guest

If my intentions are to create objects that encapsulates data rows in a
table, is it better to use a Struct or Class? Based on what i read, if my
objects will simply have get and set methods, Struct is may be better...but i
am looking for some advise from the experts on this?
Assumptions: it is possible for some operations, i may have 8000 to 10000
(or more) objects instantiated.

what are some considerations in designing a system that may instantiate this
many objects? what sort of performance advantage would Structs give me over
Classes?

thank you
 
F

Frans Bouma [C# MVP]

dimension said:
If my intentions are to create objects that encapsulates data rows in a
table, is it better to use a Struct or Class? Based on what i read, if my
objects will simply have get and set methods, Struct is may be better...but i
am looking for some advise from the experts on this?
Assumptions: it is possible for some operations, i may have 8000 to 10000
(or more) objects instantiated.

ONLY use structs for complex value types, like an int with special
characteristics. Structs are value types, not objects, so as soon as
you're using them as objects, you'll run into issues. For example, if
you index into an arraylist and do this:
((MyStructType)myArrayList[index]).Property = value;

if at that spot a struct is located, the indexer will return a copy, as
it is a value type (If I recall correctly, C# will not even compile the
above line).

So rule of thumb: almost always use classes, not structs.
what are some considerations in designing a system that may instantiate this
many objects? what sort of performance advantage would Structs give me over
Classes?

none.

FB
 
P

Peter Rilling

If you plan to provide access to the returned data via an object for each
row, it might be better to only create objects that are actually needed at
the time. You could hold the dataset in memory and have some factory class
that you can call which will create and return an object for a particular
row.
 
J

Jon Skeet [C# MVP]

Dan Kelley said:
See
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpge
nref/html/cpconvaluetypeusageguidelines.asp

Contrary top previous comments, structs can provide performance enhancements
*if used correctly*. They are allocated on the stack, not heap, and so do not
need to be managed by the GC.

They are allocated on the stack in *some* situations. If they're member
variables of an object on the heap, or static variables, or elements of
an array, or boxed, they're on the heap.

See http://www.pobox.com/~skeet/csharp/memory.html
 
W

Willy Denoyette [MVP]

Jon Skeet said:
They are allocated on the stack in *some* situations. If they're member
variables of an object on the heap, or static variables, or elements of
an array, or boxed, they're on the heap.

See http://www.pobox.com/~skeet/csharp/memory.html

And even then, they are only completely allocated on the stack if they are
composed of only value types.
Consider this:
struct st
{
public int i;
public string s; // object type - non blitable
}

void MyMethod()
{
st val; //local variable val
val.s = "test"; // the object representing the string is on the heap
...

Here val is on the stack and looks like:

address value
0x0012f600 00aa2f00 - this is a reference to the string type on the GC
heap
0x0012f604 00000000 - this is the actual value of i

address 0x0012f604 is the stack location of val.

Willy.
 
A

Alexander Muylaert

Some basic rules...

Don't use structs until you know exactly why NOT to use them...
Don't use threads until you know exactly why NOT to use them...
Don't use ...

Everybody that used threads a lot can tell you that you are better of
without. (This doesn't mean you shouldn't use them...) Same for structs,
it is'nt worth the effort.

10.000 objects... each object 32 bytes (32 bytes is an average...) ==> 312
KB. Not even half a MB.
Walk in the park...

kind regards

Alexander
 
M

Molybedenum

Alexander Muylaertwrote:
Some basic rules...
Don't use structs until you know exactly why NOT to use them...
Don't use threads until you know exactly why NOT to use them...
Don't use ...

Are you saying that if you don't know to NOT use them, then you can
use them?

You shouldn't use threads unless you understand how they work, how
concurrency works, and the issues that you will run into with them.
It isn't a matter of knowing exactly why NOT to use them, it's a
matter of knowing HOW to use them, when, and why. If you don't know
how, then don't use them.

You shouldn't use structs if you think of them as objects. In most
cases, it's best just to use classes. My opinion is that structs are
a throwback to C/C++, and are there to appease the converts from them.

*-----------------------*
Posted at:
www.GroupSrv.com
*-----------------------*
 
G

Guest

Thanks all for your feedback.
My concern is performance. So let's take this approach...

assume i don't know a thing about Structs and used them improperly, would
the worst case scenario be that i end up with basically a memory footprint
similar to a class? Are accessing methods or and properties more efficient
for one verses the other? (I know in most cases this would not make a
difference...but assuming i need to do mass processing of 10000 objects)

btw, i like the suggestion by one responder with regard to having a Factory
object keep a DataSet/Datatable in memory and returning class objects or
struct types only when needed. great idea and actually would reduce round
trips to the database, as it would be sort of like a caching mechanism.
thanks!
 
G

Guest

Oops - thought all that would be fairly obvious :) My mistake for not posting
a complete reply. Thanks for clarifying things for the OP.

Dan
 
B

Bruce Wood

dimension said:
Thanks all for your feedback.
My concern is performance. So let's take this approach...

assume i don't know a thing about Structs and used them improperly, would
the worst case scenario be that i end up with basically a memory footprint
similar to a class? Are accessing methods or and properties more efficient
for one verses the other? (I know in most cases this would not make a
difference...but assuming i need to do mass processing of 10000 objects)

btw, i like the suggestion by one responder with regard to having a Factory
object keep a DataSet/Datatable in memory and returning class objects or
struct types only when needed. great idea and actually would reduce round
trips to the database, as it would be sort of like a caching mechanism.
thanks!

In answer to your specific question, if you use structs incorrectly
you can produce absolutely horrible performance. Remember that every
time you assign a struct to a variable or pass it to a method you
create a copy. Sometimes this is exactly the behaviour you want: you
want your structure to act like an elementary type like an integer or
a decimal type. For example, I created a struct called Fraction that
has three integer fields: WholePart, Numerator, and Denominator. I
made it a struct because I want it to act exactly like an integer or a
decimal: assigning a fraction to a Fraction variable makes a copy
rather than having two variables share a reference to the same
fraction. However, the penalty I pay for this behaviour is that every
time I pass a Fraction anywhere or do any mathematics with it, I copy
three integers.

Classes behave differently. Whenever you assign one class variable to
another class variable (called reference variables), you simple copy a
reference (a pointer) from one to the other, but they now share the
same object.

There are fundamental differences between value semantics and
reference semantics in .NET. IMHO, you should not choose one over the
other because one is "more efficient". You should choose to use
structs rather than classes because your design calls for value
behaviour. You should choose classes over structs because your design
calls for reference behaviour (which is almost always the case). I ask
myself, "Is this thing I'm building like a basic value, such as an
integer or a double?" If the answer is no, then it's a class; if the
answer is yes, the it's s struct.

I don't presume to speak for programmers writing software for true
real-time systems where every clock cycle counts, although, as I've
said in other groups, if you're writing for that kind of tight
environment then I question why you're using a language with a garbage
collector, but anyway.... My take on making these decisions based on
"efficiency" is that you should do this only if you must, and only
then if you have a deep understanding of the consequences of choosing
structs over classes (value semantics over reference semantics), or
vice versa.

You can gain far more performance improvement by using appropriate
data structures and improving your overall design than you can by
making tweaks like choosing structs over classes. If you build your
application and find that it doesn't perform well, THEN profile it and
figure out where the bottlenecks are. Creating a big software mess
trying to shoehorn structs into an application in the name of
"efficiency" is generally not productive and can, as I pointed out
above, jackpot you in the end with inefficiencies that you weren't
counting on.

Design for clarity, then use the constructs that logically follow from
your design. You should deal with small-scale efficiency problems
after your application is running and you know where the problem areas
are, otherwise you're just firing blind.
 
B

Bruce Wood

dimension said:
If my intentions are to create objects that encapsulates data rows in a
table, is it better to use a Struct or Class? Based on what i read, if my
objects will simply have get and set methods, Struct is may be better...but i
am looking for some advise from the experts on this?
Assumptions: it is possible for some operations, i may have 8000 to 10000
(or more) objects instantiated.

what are some considerations in designing a system that may instantiate this
many objects? what sort of performance advantage would Structs give me over
Classes?

thank you

Looking back at your original post, I see that you're creating
business objects, presumably that encapsulate business rules and get
their data from ADO.NET data rows. This is exactly what I'm doing:
each row becomes an object with the smarts to know what the data
means, the objects are used in the application, altered, and then
written back to the database through the appropriate data rows.

If this is, in fact, what you are doing, I can state unequivocally
100% that you do not want these things to be structs. If you attempt
to make them structs you will run into all sorts of problems, such as
wondering why when you put them in an aggregate structure and try to
change them they don't change:

MyStruct s = (MyStruct)myHashTable[key];
s.Description = "New description";

then next time you look up myHashTable[key] you find that it still
contains the old description.

Stuff like that that will leave you scratching your head until you
finally realize that no, in fact these things shouldn't be structs,
they should be classes... and then you have to redo the whole project.

As well, if you're building objects as I described, then consider the
following. You are reading all of these objects from a database into
ADO.NET data tables. The operation of going to a database, executing a
SQL query, creating appropriate ADO.NET tables, and populating them
with data is so outrageously expensive compared to the cost--both in
terms of cycles and memory--involved in working with either structs or
classes at the end of it all that choosing one construct over the
other will make absolutely no noticeable performance difference. None.
Squat. ADO.NET uses relatively large amounts of memory, and executing
database queries, particularly over networks, comes with such a
serious performance penalty that anything you're doing locally in your
own CPU and your own memory likely pales in comparison.

If you choose one construct over the other for "performance" reasons,
and actually manage to choose correctly (which would be beyond my ken,
at least), then you may be able to shave a millisecond off an
operation than then heads off into the bowels of ADO.NET for a second
or two to fetch data or write it back across the network into the
database.

Instead of trying to shave a millisecond off your execution time, or
save 10K of memory, you would be much better off optimizing your
database access or being careful in your use of ADO.NET to save
seconds of execution time and hundreds of K of memory.

As I said: build it first according to solid design principles. Then
figure out where it's slow / a memory pig using a profiler, and
concentrate on those areas.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top