当前位置: 首页 > 图灵资讯 > 行业资讯> Jupyter Notebook怎么设置运行耗时统计

Jupyter Notebook怎么设置运行耗时统计

来源:图灵python
时间: 2026-08-10 21:57:30
最省事的方案是安装jupyter_contrib_nbextensions,使用Executetensions Time插件自动显示单元格运行耗时;%time测量单行,%time测量整个单元格,但不持久;GPU代码需要同步;%timeit适合多轮性能比较;手写计时推荐perf_counter()避免变量污染。

直接启用 Execute Time 扩展最省事

如果你只是想在每个单元下自动显示「最后一次运行需要时间」,无需编写代码或更改配置即可安装 jupyter_contrib_nbextensions 并启用 Execute Time 插件。将时间写在单元格的底部,重启 kernel 保留后(只要输出没有清空)。

常见失败点:jupyter nbextension enable execute_time/Exec 报错或者没有反应,大概率是没有配套的 configurator 或者版本不匹配。必须按顺序执行:

  • pip install jupyter_contrib_nbextensions jupyter_nbextensions_configurator
  • jupyter contrib nbextension install --user
  • jupyter nbextension enable execute_time/Exec

装完重启 Jupyter(不是 reload 页面,是关闭过程 jupyter notebook 重开),然后在菜单栏找到, Nbextensions → 搜索 time → 勾选 Execute Time → 确保右下角 Disable configuration for user extensions **没有检查**。

%time 和 %%time 必须区分行为差异

%time 只测单行,%%time 测整个 cell —— 但是,它们在当前执行过程中只显示一次结果,不会持续记录。而且 %%time 必须写在 cell 第一行,后面不能跟代码;%time 可插入任何行前。

容易踩的坑:

  • %%time 包括所有句子,包括 import、但不包括变量定义和循环体 cell 之前的 state(比如前面 cell 已加载的模块)
  • GPU 代码(如 PyTorch/CUDA)用 %%time 由于真实耗时会被严重低估,因此会被严重低估 CUDA 是异步提交。必须添加 torch.cuda.synchronize()cupy.cuda.Device().synchronize() 才准
  • 如果 cell 输出被 ; 抑制,%%time 耗时信息仍将打印在输出区顶部,不会消失
%%timeit 更适合比较算法性能

当你想判断「A 写法 vs B 写法哪个快」,别信单次 %%time,用 %%timeit。它自动运行多轮,消除异常值,给出平均值和标准差,如:

Jupyter Notebook 7.5.4

Jupyter Notebook 7.5.4 官方 PyPI wheel 包下载适用于本地交互式代码运行、数据分析、教学演示和文件配置实践。

下载

%%timeit -n 10 -r 5
x = [i**2 for i in range(10000)]

意思是:每轮跑 10 次,共跑 5 轮,最后报告「平均单次耗时 ± 标准差」。注意:%%timeit 默认会忽略第一轮(预热),不包括在内 setup 代码(比如 import)—— 如果 setup 很重,得用 -s 单独指定参数。

关键限制:

  • %%timeit 不支持交互式变量引用(例如依赖上一个) cell 定义的 df),所有的依赖都必须写在当前 cell 里
  • 它将反复执行整个过程 cell,因此,不能用于有副作用的操作(如写文件、改变整体状态、调整等) API)
  • 默认最大的尝试次数是 1000 一万次,太慢的代码会提前停止,可以添加 -o 查看详细的配置
自定义计时器应小心内核状态污染

如果扩展和 magic 都不够(比如想跨 cell 可以手写累计耗时或多个阶段) time.perf_counter()。但别直接用 time.time() —— 它受系统时钟调整的影响,perf_counter() 是高精度单调时钟。

示例:

import time
start = time.perf_counter()
# your code here
end = time.perf_counter()
print(f"耗时: {end - start:.4f}s")

真正容易被忽视的是:Jupyter kernel 它是连续运行的,变量不会自动清理。如果你在不同的地方 cell 里重复定义 start,旧值可能会意外重复使用。更安全的方法是添加前缀或使用字典:

  • 每次使用独立变量名:start_load_data, start_train
  • 或者统一用 timing_log = {},配合 timing_log['load'] = time.perf_counter()
  • 永远不要在函数中使用 global start —— kernel 变量在重启后丢失,但函数仍然存在,将报告 NameError