Python中如何实现函数级/代码块级计时器功能

https://www.jianshu.com/p/c890d5258ac9
Python中如何实现函数级/代码块级计时器功能

12 回复

卧槽 我刚写了个类似的文章~


在Python里给函数或代码块计时,直接用time模块的time.perf_counter()就行,它精度高。更省事的办法是用timeit模块,或者自己写个装饰器。

1. 基础手动计时

import time

start = time.perf_counter()
# 你的代码块
time.sleep(0.1)
end = time.perf_counter()
print(f"耗时: {end - start:.6f} 秒")

2. 使用装饰器(函数级计时) 这个最方便,加个@就能给任何函数计时。

import time
import functools

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        end = time.perf_counter()
        print(f"函数 {func.__name__} 耗时: {end - start:.6f} 秒")
        return result
    return wrapper

@timer
def my_function():
    time.sleep(0.5)

my_function()

3. 使用上下文管理器(代码块级计时)with语句控制计时范围,很清晰。

import time
from contextlib import contextmanager

@contextmanager
def code_block_timer(name="代码块"):
    start = time.perf_counter()
    yield
    end = time.perf_counter()
    print(f"{name} 耗时: {end - start:.6f} 秒")

with code_block_timer("数据加载"):
    time.sleep(0.3)

4. 使用内置的timeit模块 适合快速测试小段代码的性能。

import timeit

code_to_test = """
sum(range(1000))
"""
execution_time = timeit.timeit(stmt=code_to_test, number=10000)
print(f"执行10000次总耗时: {execution_time:.6f} 秒")

总结:日常用装饰器或上下文管理器最省事。

哈哈,握手,发出来看看啊

可能没啥用 哈哈

我能想到的基本也就这两种方法了…

哈哈哈哈有种被钦定的感觉

说明 best practice 是全球通用的 !😷

如果只是简单的计数,我觉得这个实现问题不大,如果是为了做性能剖析采样的话。

uber 的 pyflame,无入侵式,可以生成火焰图,看火焰图就差不多了。

如果想跟进一步做 timer 的话,可以使用 CPython 的 Profiling API,Pycharm 也是用对应的 API 实现 Debugger 的。精确到行级,性能更高。

pyflame 之前不了解,无侵入式倒是很有意思,不知道是怎么做到的,谢谢推荐。profile 的话场景感觉有点不一样,目前我工程上主要是用计时器在生产时输出日志。

非侵入式,当然是要考虑 dtrace, bpf, ptrace 之类的工具,然后再对应回你的源代码。

回到顶部