1

if i've a program running on a server, which one will use more memory:

a = operation1()

b = operation2()

c = doOperation(a, b)

or directy:

a = doOperation(operation1(), operation2())

Edit:

1: i'm using CPython.

2: i'm asking this question because sometimes, i love readability in my code, so instead of writing looong sequences of operation, u just split them into variables.

Edit2:

here is the full code:

class Reset(BaseHandler):
@tornado.web.asynchronous
@tornado.gen.engine
def get(self, uri):
    uri = self.request.uri
    try:
        debut = time.time()
        tim = uri[7:]
        print tim
        cod = yield tornado.gen.Task(db.users.find_one, ({"reset.timr":tim})) # this is temporary variable
        code = cod[0]["reset"][-1]["code"] # this one too
        dat = simpleencode.decode(tim, code)
        now = datetime.datetime.now() # this one too
        temps = datetime.datetime.strptime(dat[:19], "%Y-%m-%d %H:%M:%S") # this one too
        valid = now - temps # what if i put them all here
        if valid.days < 2:
            print time.time() - debut # here time.time() has not been set to another variable, used directly
            self.render("reset.html")
        else:
            self.write("hohohohoo")
            self.finish()
    except (ValueError, TypeError, UnboundLocalError):
        self.write("pirate")
        self.finish()

as you can see there are variables that are only temporarly useful.

Abdelouahab Pp
  • 4,252
  • 11
  • 42
  • 65
  • 3
    That depends entirely on wether or not `doOperation()` will store references to the arguments passed in. – Martijn Pieters Feb 08 '13 at 14:45
  • 1
    @MartijnPieters -- and on when the garbage collector actually runs I suppose ... – mgilson Feb 08 '13 at 14:48
  • 2
    @mgilson: In CPython objects are deleted the moment the ref count drops to 0; the garbage collector is mostly needed to detect and break circular references. – Martijn Pieters Feb 08 '13 at 14:50
  • 1
    @mgilson: in CPython, the garbage collector is only for reclaiming cycles. Normal zero-referenced memory is reclaimed as soon as the reference count hits zero. – Ned Batchelder Feb 08 '13 at 14:50
  • 1
    @MartijnPieters -- Here we go again with the pretending that CPython is the only implementation that exists ;-). Does it work that way with `Jython` or `Pypy` or `IronPython`? (I don't know the answer to that question ... but it's worth asking I think) – mgilson Feb 08 '13 at 14:54
  • 3
    @mgilson: notice that among the startling similarities between Martijn's answer and mine, we both explicitly mentioned CPython. No one is pretending! :) Both Jython and IronPython use a more traditional wait-and-pause garbage collector. PyPy has a few options for garbage collector. – Ned Batchelder Feb 08 '13 at 14:55
  • 1
    @mgilson: Garbage collection is certainly different in Jython and IronPython; don't know much about what PyPy does. – Martijn Pieters Feb 08 '13 at 14:55
  • 1
    @NedBatchelder -- Yeah, I realize that. But Martijn and I have been though this before and I was just protecting my comment ;-). If different python implementations behave differently in this regard, than that's potentially information that OP (or someone else with this same question) might want to know. – mgilson Feb 08 '13 at 15:01

2 Answers2

2

Provided doOperation() does not clear it's own references to the arguments passed in, or create more references to the arguments, until doOperation() completes, the two approaches are exactly the same.

The latter will use less memory once doOperation() completes, because by then the local variables of the function are cleaned up. In the first option, because a and b still hold references, the ref count does not drop to 0.

CPython uses reference counting to clean up any objects that are no longer used; once the reference count drops to 0 objects are automatically cleaned up.

If memory and readability are a concern, you can delete references explicitly:

a = operation1()
b = operation2()

c = doOperation(a, b)

del a, b

but remember that local variables inside a function are cleaned up automatically, so the following would also result in the a and b references being removed:

def foo():
    a = operation1()
    b = operation2()

    c = doOperation(a, b)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

Memory occupied by values will only be reclaimed when the values are no longer referenced. Just looking at the examples you gave, it's impossible to tell when those values are no longer referenced, because we don't know what doOperation does.

One thing to keep in mind: assignment never copies values, so merely assigning a value to a name won't increase the memory use.

Also, unless you have an actual memory problem, don't worry about it. :)

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 1
    storing the names of the local variables, of course, will use some memory... (if this is relevant in any real situation you almost certainly don't want to be using Python) – Wooble Feb 08 '13 at 14:52
  • because in python, i found somewhere (dont remember) that it dont uses assignement! – Abdelouahab Pp Feb 08 '13 at 14:58
  • 1
    @AbdelouahabPp: you should read more about how Python actually works. "It doesn't use assignment" is certainly misleading... – Ned Batchelder Feb 08 '13 at 15:00
  • @NedBatchelder no, i remember the guy in some blog said: in python it's not the same thing as C, since everything is an object, then it's king of inheritence? – Abdelouahab Pp Feb 08 '13 at 15:04
  • 1
    @AbdelouahabPp: Read this [previous answer of mine](http://stackoverflow.com/questions/12080552/python-list-doesnt-reflect-variable-change-new-to-python/12080644#12080644). Python has a really large ball of string, and endless little labels instead.. – Martijn Pieters Feb 08 '13 at 15:07
  • @MartijnPieters i just updated the question with the code, so as you can see, i want to delete those references and use all variables in one long operation, readability will be horrible, but this will free memory? – Abdelouahab Pp Feb 08 '13 at 15:10
  • 1
    @AbdelouahabPp: The memory footprint of that code is *not going to be a problem*. Stop worrying about it. – Martijn Pieters Feb 08 '13 at 15:12
  • @MartijnPieters yes, but it's only a simple operation of a long program, so i said that maybe i can save some kilobytes to become megabytes when lot of users clic on the page ;) – Abdelouahab Pp Feb 08 '13 at 15:14
  • 1
    @AbdelouahabPp: Get to the point where you have enough users for this to become a problem first, then when you get there, you have a large enough budget to scale this baby out to multiple machines. Trust me on this. – Martijn Pieters Feb 08 '13 at 15:16
  • @MartijnPieters yes, but i just wanted to understand Garbage collector in python before being rich :p – Abdelouahab Pp Feb 08 '13 at 15:18