Python - Timeit внутри класса - PullRequest
       6

Python - Timeit внутри класса

4 голосов
/ 31 августа 2010

У меня есть реальная проблема с синхронизацией функции из экземпляра класса. Я не уверен, что поступлю правильно (никогда раньше не использовал timeIt), и я попробовал несколько вариантов импорта второго аргумента, но не повезло. Вот глупый пример того, что я делаю:

import timeit

class TimedClass():
    def __init__(self):
        self.x = 13
        self.y = 15
        t = timeit.Timer("self.square(self.x, self.y)")
        try:
            t.timeit()
        except:
            t.print_exc()

    def square(self, _x, _y):
        print _x**_y

myTimedClass = TimedClass()

Который, когда бежит, жалуется на себя.

Traceback (most recent call last):
  File "timeItTest.py", line 9, in __init__
    t.timeit()
  File "C:\Python26\lib\timeit.py", line 193, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
    self.square(self.x, self.y)
NameError: global name 'self' is not defined

Это связано с тем, что TimeIt создает небольшую виртуальную среду для запуска функции, но что мне нужно передать второму аргументу, чтобы все это было счастливым?

Ответы [ 4 ]

10 голосов
/ 31 августа 2010

Если вы готовы рассмотреть альтернативы timeit, я недавно нашел утилиту таймера секундомер , которая может быть полезна в вашем случае.это действительно просто и интуитивно понятно:

import stopwatch

class TimedClass():

    def __init__(self):
        t = stopwatch.Timer()
        # do stuff here
        t.stop()
        print t.elapsed
9 голосов
/ 31 августа 2010

Почему вы хотите, чтобы время внутри класса было синхронизировано? Если вы берете время вне класса, вы можете просто передать ссылку. * 1001 Т.е. *

import timeit

class TimedClass():
    def __init__(self):
        self.x = 13
        self.y = 15

    def square(self, _x, _y):
        print _x**_y

myTimedClass = TimedClass()
timeit.Timer(myTImedClass.square).timeit()

(конечно, сам класс избыточен, я предполагаю, что у вас есть более сложный вариант использования, когда простого метода недостаточно).

В общем, просто передайте вызываемый объект, который содержит / настроил все настройки. Если вы хотите передать строки для синхронизации, они должны содержать все необходимые настройки внутри них, т.е.

timeit.Timer("[str(x) for x in range(100)]").timeit()

Если вам действительно очень нужно время внутри класса, оберните вызов в локальный метод, т.е.

def __init__(self, ..):
    def timewrapper():
        return self.multiply(self.x, self.y)

    timeit.Timer(timewrapper)
4 голосов
/ 30 марта 2016

Чтобы устранить вашу первоначальную ошибку, вы можете использовать timeit внутри класса с такими параметрами:

 t = timeit.Timer(lambda: self.square(self.x, self.y)).timeit()
0 голосов
/ 13 ноября 2014

(публикация в качестве ответа, потому что кодовая разметка не работает в комментарии)

Я бы добавил закрытие попытка / окончание для дополнительной безопасности:

class TimedClass():
  def __init__(self):
    t = stopwatch.Timer()
    try:
      # do stuff here, you can even use return "foo" here and throw exceptions
    finally:
      t.stop()
      print t.elapsed
...