Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use if statements to micromanage stack

Tags:

c#

Should if statements be used to assist in the stack's memory de-allocation?

Example A:

        var objectHolder = new ObjectHolder();
        if (true)
        {
            List<DefinedObject> objectList;
            using (var sr = new GenericStreamReader<DefinedObject>())
            {
                objectList= sr.Get().ToList();
            }
            if (true)
            {
                var DOF = new DefinedObjectFactory();
                objectHolder.DefinedObjects = DOF.DefineObjects(objectList);
            }
        }
        //example endpoint

Example B:

        var objectHolder = new ObjectHolder();
        List<DefinedObject> objectList;
        using (var sr = new GenericStreamReader<DefinedObject>())
        {
         objectList= sr.Get().ToList();
        }
        var DOF = new DefinedObjectFactory();
        objectHolder.DefinedObjects = DOF.DefineObjects(objectList);
        //example endpoint

Will Example A have a lighter footprint on the stack when example endpoint is reached versus when example endpoint is reached in Example B??

like image 740
Travis J Avatar asked Nov 28 '22 03:11

Travis J


2 Answers

First off, the whole point of a stack-based allocation system is precisely that you do not need to optimize it in any way. Don't worry about it. The jitter is perfectly capable of realizing that a local will never be read or written again, and re-using its storage if it feels that's the best thing to do. Let the jitter do its job; it doesn't need your help. (*)

Rather, write your program so that local variables make sense to the reader. That's what you should be optimizing for.

Finally, there is never a need to say "if (true) { }" to introduce a new scope. Just introduce a new scope. It is perfectly legal to say:

void M()
{
    { // new scope
    }

    { // another one
    }
} 

(*) There is a situation where the jitter needs your help, and that is the situation where a local refers to an object on the heap that contains a resource that is going to be used by unmanaged code. The jitter does not know that unmanaged code is going to use the object's resources, and might decide that no one is using this object any more and clean it up early. The finalizer of the object might then release the resource on the finalizer thread while the unmanaged code is using the resource! An object is not guaranteed to stay alive just because a local variable is holding onto it. If the local variable is never read from again then the jitter can re-use its storage and tell the garbage collector that it is safe to collect the referred-to object, which will then potentially crash the unmanaged code. You can use KeepAlive to hint to the jitter that a particular object needs to remain alive and not be optimized away.

like image 154
Eric Lippert Avatar answered Dec 05 '22 01:12

Eric Lippert


if(true) will be compiled out in optimized build (the only build where variable lifespan is shorter than whole method) - so there is absolutely no difference between two versions you've suggested.

like image 38
Alexei Levenkov Avatar answered Dec 05 '22 01:12

Alexei Levenkov