Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r72315:bbabcc9974eb Date: 2014-07-02 17:06 +0200 http://bitbucket.org/pypy/pypy/changeset/bbabcc9974eb/
Log: Tweaks to timeit.py: * don't use itertools.repeat(), just plainly do "while n > 0: n -= 1". * recompile the source code each time before calling inner(). There are situations like Issue #1776 where PyPy tries to reuse the JIT code from before, but that's not going to work: the first thing the function does is the "-s" statement, which may declare new classes (here a namedtuple). We end up with bridges from the inner loop; more and more of them every time we call inner(). diff --git a/lib-python/2.7/timeit.py b/lib-python/2.7/timeit.py --- a/lib-python/2.7/timeit.py +++ b/lib-python/2.7/timeit.py @@ -55,11 +55,6 @@ import gc import sys import time -try: - import itertools -except ImportError: - # Must be an older Python version (see timeit() below) - itertools = None __all__ = ["Timer"] @@ -81,7 +76,8 @@ def inner(_it, _timer): %(setup)s _t0 = _timer() - for _i in _it: + while _it > 0: + _it -= 1 %(stmt)s _t1 = _timer() return _t1 - _t0 @@ -96,7 +92,8 @@ def inner(_it, _timer, _func=func): setup() _t0 = _timer() - for _i in _it: + while _it > 0: + _it -= 1 _func() _t1 = _timer() return _t1 - _t0 @@ -133,9 +130,11 @@ else: raise ValueError("setup is neither a string nor callable") self.src = src # Save for traceback display - code = compile(src, dummy_src_name, "exec") - exec code in globals(), ns - self.inner = ns["inner"] + def make_inner(): + code = compile(src, dummy_src_name, "exec") + exec code in globals(), ns + return ns["inner"] + self.make_inner = make_inner elif hasattr(stmt, '__call__'): self.src = None if isinstance(setup, basestring): @@ -144,7 +143,8 @@ exec _setup in globals(), ns elif not hasattr(setup, '__call__'): raise ValueError("setup is neither a string nor callable") - self.inner = _template_func(setup, stmt) + inner = _template_func(setup, stmt) + self.make_inner = lambda: inner else: raise ValueError("stmt is neither a string nor callable") @@ -185,15 +185,12 @@ to one million. The main statement, the setup statement and the timer function to be used are passed to the constructor. """ - if itertools: - it = itertools.repeat(None, number) - else: - it = [None] * number + inner = self.make_inner() gcold = gc.isenabled() if '__pypy__' not in sys.builtin_module_names: gc.disable() # only do that on CPython try: - timing = self.inner(it, self.timer) + timing = inner(number, self.timer) finally: if gcold: gc.enable() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit