What does timeit gain by turning off garbage collection?
Asked Answered
Z

2

7

I was reading the code for the timeit module and I noticed this segment:

gcold = gc.isenabled()
gc.disable()
timing = self.inner(it, self.timer)
if gcold:
    gc.enable()

This just stores the state of garbage collection (on or off) and then turns it off. The function inner executes the statement being timed. It then reverts the garbage collector to its old state.

So I'm curious about what the point of this is. If the code being tested works the garbage collector, then shouldn't that be reflected in the testing? What am I missing?

Zayas answered 24/12, 2010 at 2:14 Comment(0)
M
7

The nature of garbage collection is that its frequency and duration is somewhat unpredictable. At least from the point of view of the performance of a specific chunk of code, the garbage collector just adds noise to the statistics.

From a whole-program point of view, you are correct in that if your program is running on a system where the garbage collector is exercised, then yes that should be taken into account when measuring the program performance. But it's not usually factored in for individual functions.

Machado answered 24/12, 2010 at 2:19 Comment(3)
But CPython at least uses reference counting for everything but cycles. This is perfectly deterministic. I see your point though as it relates to other implementations. I wasn't thinking about that. I guess even in CPython, there's no telling when it will search for references.Zayas
The Python garbage collector does a lot less than people think -- in fact it collects only cyclic references. But when was the last time you used one of these? For me, it was when i wanted to show what the garbage collector does, but never in production code. So I think it's pretty safe to assume that the GC does in fact do nothing in your average code, so you might as well disable it to avoid random slowdowns.Fireboard
@THC4k: That's true, for CPython. Other implementations may behave differently (eg. IronPython will use the CLR collector).Machado
K
7

Surely that code should be written like this?

gcold = gc.isenabled()
gc.disable()
try:
    timing = self.inner(it, self.timer)
finally:
    if gcold:
        gc.enable()

Otherwise garbage collection will remain disabled if the timed code throws an exception.

I reported this on bugs.python.org, and it was fixed in Python 2.7.3 and 3.2.2.

Koralie answered 7/7, 2011 at 15:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.