Skip to content

Instantly share code, notes, and snippets.

@MestreLion
Created October 8, 2021 04:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MestreLion/c52c89f76d3fa979f48c53fcd912b463 to your computer and use it in GitHub Desktop.
Save MestreLion/c52c89f76d3fa979f48c53fcd912b463 to your computer and use it in GitHub Desktop.
Python __iter__() performance: iter() vs yield from vs for
#!/usr/bin/env python3
# Iter vs Yield vs For
# Copyright (C) 2021 Rodrigo Silva (MestreLion) <linux@rodrigosilva.com>
# License: GPLv3 or later, at your choice. See <http://www.gnu.org/licenses/gpl>
import collections.abc
import timeit
class Base(collections.abc.MutableMapping):
def __init__(self, items: dict = None): self._items: dict = items or {}
def __getitem__(self, key): return self._items[key]
def __len__(self): return len(self._items)
def __setitem__(self, key, value): self._items[key] = value
def __delitem__(self, key): del self._items[key]
def __contains__(self, key): return key in self._items # optional
def __str__(self): return self.__class__.__name__
def __iter__(self): raise NotImplementedError
class Iter(Base):
def __iter__(self): return iter(self._items)
class Yield(Base):
def __iter__(self): return (yield from self._items)
class For(Base):
def __iter__(self):
for _ in self._items: yield _
def iterate(i):
for _ in i: pass
d = {f"{k:03}": k for k in range(10)}
print("Benchmarking __iter__")
for cls in (Iter, Yield, For):
iterator = cls(d)
name = str(iterator)
t = timeit.timeit(lambda: iterate(iterator))
print(f"{name:5}: {t}")
# Benchmarking __iter__
# Iter : 0.3709624619805254
# Yield: 0.626235187985003
# For : 0.656251213978976
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment