Python - 类中的 Timeit

发布于 2024-09-16 20:32:13 字数 868 浏览 9 评论 0原文

我在从类的实例中计时函数时遇到了一些真正的麻烦。我不确定我是否以正确的方式处理它(以前从未使用过 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 创建一个小的虚拟环境来运行该函数有关,但是我必须传递给第二个参数什么才能使它一切顺利?

I'm having some real trouble with timing a function from within an instance of a class. I'm not sure I'm going about it the right way (never used timeIt before) and I tried a few variations of the second argument importing things, but no luck. Here's a silly example of what I'm doing:

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()

Which, when ran, complains about self.

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

This has to do with TimeIt creating a little virtual environment to run the function in but what do I have to pass to the second argument to make it all happy?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

忆梦 2024-09-23 20:32:13

如果您愿意考虑 timeit 的替代方案,我最近发现了 stopwatch 计时器实用程序,这可能对您的情况有用。它也非常简单直观:

import stopwatch

class TimedClass():

    def __init__(self):
        t = stopwatch.Timer()
        # do stuff here
        t.stop()
        print t.elapsed

if you're willing to consider alternatives to timeit, i recently found the stopwatch timer utility which might be useful in your case. it's really simple and intuitive, too:

import stopwatch

class TimedClass():

    def __init__(self):
        t = stopwatch.Timer()
        # do stuff here
        t.stop()
        print t.elapsed
游魂 2024-09-23 20:32:13

为什么你希望课堂内的计时自行计时?如果你把时间从课堂上拿出来,你可以只传递一个推荐信。即

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)

Why do you want the timing inside the class being timed itself? If you take the timing out of the class, you can just pass a reference. I.e.

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()

(of course the class itself is redundant, I assume you have a complexer use-case where a simple method is not sufficient).

In general, just pass a callable that has all setup contained/configured. If you want to pass strings to be timed they should contain all necessary setup inside them, i.e.

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

If you really, really need the timing inside the class, wrap the call in a local method, i.e.

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

    timeit.Timer(timewrapper)
但可醉心 2024-09-23 20:32:13

要解决最初的错误,您可以在类中使用 timeit 并使用如下参数:

 t = timeit.Timer(lambda: self.square(self.x, self.y)).timeit()

To address your initial error, you can use timeit within a class with parameters like this:

 t = timeit.Timer(lambda: self.square(self.x, self.y)).timeit()
涫野音 2024-09-23 20:32:13

只需将 self 传递给 timeit.Timer() 的新 globals 参数(在 3.5 版本中添加):

import timeit

class TimedClass():
    def __init__(self):
        self.x = 13
        self.y = 15
        my_globals = globals()
        my_globals.update({'self':self})
        t = timeit.Timer(stmt="self.square(self.x, self.y)", globals=my_globals)
        try:
            t.timeit()
        except:
            t.print_exc()

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

myTimedClass = TimedClass()

Just pass self through the new globals parameter of timeit.Timer() (added in version 3.5):

import timeit

class TimedClass():
    def __init__(self):
        self.x = 13
        self.y = 15
        my_globals = globals()
        my_globals.update({'self':self})
        t = timeit.Timer(stmt="self.square(self.x, self.y)", globals=my_globals)
        try:
            t.timeit()
        except:
            t.print_exc()

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

myTimedClass = TimedClass()
浅暮の光 2024-09-23 20:32:13

(作为答案发布,因为代码标记在评论中不起作用)

我会添加一个 try/finally 闭包以提高安全性:

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

(posting as an answer because the code markup does not work in a comment)

I would add a try/finally closure for additional safety:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文