tags:

views:

210

answers:

6

In C#, does the following save any memory?

private List<byte[]> _stream;
public object Stream
{
    get
    {
        if (_stream == null)
        {
            _stream = new List<byte[]>();
        }
        return _stream;
    }
}

Edit: sorry, I guess I should have been more specific.

Specifically using "object" instead of List... I thought that would kinda clue itself in because it's a weird thing to do.

+1  A: 

Save memory compared to what?

 byte[][] _stream;

maybe? Then no, a List<T> will take up more memory since it is an array at its heart (which isn't necessarily exactly the size of its contents, but usually larger) and some statekeeping needs to be done too.

Joey
A: 

Are you sure a Stream wouldn't be just a byte[] or a List of byte? Or even better, a MemoryStream? :) I think you are somewhat confused, so a bigger example and some scenario details will help a lot.

Paul Betts
+5  A: 

It saves a very small amount of memory. The amount of memory an empty List<byte[]> is going to take up is byte size.

The reason why is that your reference variable _stream only needs to allocate enough memory to hold a reference to an object. Once an object is allocated, it will take up a certain amount of memory which may grow or shrink over time, such as when new byte[]s are added to the List. However the memory taken up by the reference to that object will remain the same size.

This is simpler and less prone to corner cases that cause you headaches:

private List<byte[]> _stream = new List<byte[]>();
public object Stream
{
    get
    {
        return _stream;
    }
}

Although, in most cases it's not really optimal to be returning references to private members when they are collections/arrays, etc. Better to return _stream.AsReadOnlyCollection().

SoloBold
A: 

What are objects really

I'd suggest thinking in objects as structs... and object references as pointers to that structure.

If you instantiate an object you are reserving memory for an "struct" with all its fields (and a reference to the class it's implementing), plus all memory reserved by the constructor (other objects, arrays, etc...).

In List you are reserving memory for state keeping (I don't know how it's implemented in C#) and the initial internal array, maybe of ten references. So... if you count its something like (assuming 32 bits runtime, I'm not a .net specialist):

  • pointer to class: 4 bytes
  • pointer to array: 4 bytes
  • array of initialCapacity references: 40 bytes

So in my estimation it's about 48 bytes. But it depends on the implementation.

As SoloBold says: most of times it's not worthy.

helios
Oh no, please don't do that. Because structs are value types they have very different semantics than reference types. It is grossly misleading to try to think of classes as being special structs or vice-versa.
Jason
MMm maybe my post is misleading. When I coursed CS, my first classes where aboud abstract data types, and we used functions over pointers to structs. That was pretty close to objects, no because the structs were objects but because the reference to the object is implemented by a pointer to a struct. When you do "Client a = new Client()" is like "StClient* a = malloc(sizeof(StClient))" where StClient has all the fields of object Client (I'm ignoring subobjects). If you think about what pieces of mem works behind the scene all the picture become clear.
helios
+1  A: 

That is a lazy loading. You will create the stream only when someone requests it. It will not create the stream (in your case a list) unless is required.

One might say that it saves some memory because it will not use any unless required. So before using the stream there is no memory allocated for it.

Victor Hurdugaci
+1  A: 

If your edit indicates that you are asking whether the use of the object keyword instead of List<byte[]> as the type of the property saves memory, no, it doesn't. And your if block only saves a negligible amount of memory (and cpu at instantiation) until the first time the property is called. And it does make the first call to that property slightly slower. Consider returning a null instead if it makes sense for the property. And, like another answerer suggested, it may be better to keep the property read-only unless you'd like other classes to be altering it. In general, I'd say attempts at optimization like this are mostly misguided and make your code less maintainable.

Eric Mickelsen
Thanks, good points
Skawful