Reputation: 5228
As a programmer, I generally try to avoid the del
statement because it is often an extra complication that Python program don't often need. However, when browsing the standard library (threading
, os
, etc...) and the pseudo-standard library (numpy
, scipy
, etc...) I see it used a non-zero amount of times, and I'd like to better understand when it is/isn't appropriate the del
statement.
Specifically, I'm curious about the relationship between the Python del
statement and the efficiency of a Python program. It seems to me that del
might help a program run faster by reducing the amount of clutter lookup instructions need to sift through. However, I can also see a world where the extra instruction takes up more time than it saves.
My question is: does anyone have any interesting code snippets that demonstrate cases where del
significantly changes the speed of the program? I'm most interested in cases where del
improves the execution speed of a program, although non-trivial cases where del
can really hurt are also interesting.
Upvotes: 3
Views: 2032
Reputation: 129507
Specifically, I'm curious about the relationship between the Python
del
statement and the efficiency of a Python program.
As far as performance is concerned, del
(excluding index deletion like del x[i]
) is primarily useful for GC purposes. If you have a variable pointing to some large object that is no longer needed, del
ing that variable will (assuming there are no other references to it) deallocate that object (with CPython this happens immediately, as it uses reference counting). This could make the program faster if you'd otherwise be filling your RAM/caches; only way to know is to actually benchmark it.
It seems to me that
del
might help a program run faster by reducing the amount of clutter lookup instructions need to sift through.
Unless you're using thousands of variables (which you shouldn't be), it's exceedingly unlikely that removing variables using del
will make any noticeable difference in performance.
Upvotes: 0
Reputation: 488213
The main reason that standard Python libraries use del
is not for speed but for namespace decluttering ("avoiding namespace pollution" is another term I believe I have seen for this). As user2357112 noted in a comment, it can also be used to break a traceback cycle.
Let's take a concrete example: line 58 of types.py in the cpython implementation reads:
del sys, _f, _g, _C, _c, # Not for export
If we look above, we find:
def _f(): pass
FunctionType = type(_f)
LambdaType = type(lambda: None) # Same as FunctionType
CodeType = type(_f.__code__)
MappingProxyType = type(type.__dict__)
SimpleNamespace = type(sys.implementation)
def _g():
yield 1
GeneratorType = type(_g())
_f
and _g
are two of the names being del
ed; as the comment says, they are "not for export".1
You might think this is covered via:
__all__ = [n for n in globals() if n[:1] != '_']
(which is near the end of that same file), but as What's the python __all__ module level variable for? (and the linked Can someone explain __all__ in Python?) note, these affect the names exported via from types import *
, rather than what's visible via import types; dir(types)
.
It's not necessary to clean up your module namespace, but doing so prevents people from sneaking into it and using undefined items. So it's good for a couple of purposes.
1Looks like someone forgot to update this to include _ag
. _GeneratorWrapper
is harder to hide, unfortunately.
Upvotes: 3