微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Timeit.timeit 方法哪种方式是正确的:内部还是外部?

如何解决Timeit.timeit 方法哪种方式是正确的:内部还是外部?

我想检查每个功能的速度,但遇到了问题。如您所见,下面的代码包含两个相同的函数func & func2。但是func是直接在timeit.timeit方法中声明的。经过测试,得到了一个结果:Func result: 0.08,func 2 result: 0.21.。这是一个巨大的差异。

这里有一个问题:为什么相同的功能有不同的速度?从全局范围获取 func2 需要时间吗?

import timeit


def func2() -> range:
    return range(1024)


def main():
    """
    Number of seconds for each function to perform with 500k executions
    """
    func_res = round(timeit.timeit(
        'def func() -> range: return range(1024); func()',number=500_000
        ),2)
    func2_res = round(timeit.timeit(
        'func2()',number=500_000,globals=globals()
        ),2)
    return f'Func result: {func_res},func 2 result: {func2_res}.'

if __name__ == '__main__':
    print(main())

P.S. 'def func() -> range: return range(1024)' ---> 'def func() -> range: return range(1024); func()' 已编辑。

解决方法

您正在测试的两个语句完全不同。

第一个 (def func() -> range: return range(1024); func()) 仅测试 Python 在声明具有 return range(1024); func() 主体的函数时的速度。第二个实际上调用了该函数。

由于 timeit 也可以接受可调用对象,因此您可以这样做

timeit.timeit(
    func2,number=500_000,)

无论如何。

让我们尝试使用更好的测试平台:

import timeit


def func2() -> range:
    return range(1024)


def t(name,stmt,setup="pass"):
    res = timeit.timeit(stmt,setup,number=5_000_000,globals=globals()) * 1000
    print(f"{name:>25} {int(res):5d}")


def main():
    t("declare a func","def func() -> range: return range(1024); func()")
    t("declare & run func","def func() -> range: return range(1024)\nfunc()")
    t("run local func","func()","def func() -> range: return range(1024)")
    t("run global func2 by name","func2()")
    t("run func2 by ref",func2)


if __name__ == "__main__":
    main()

您可以看到声明 func 调用它的选项也慢得多(我机器上的数字,YMMV):

           declare a func   547  # <-- doesn't call range!
       declare & run func  1282  # <-- slow...
           run local func   854  # <-- declare function once & call it
 run global func2 by name   836
         run func2 by ref   774

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。