You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jupyter Notebook单元格重运行为何快于首次运行?特定场景解析

Jupyter Notebook单元格重运行加速现象解析

测试代码

#Start of Cell 1____________________________________________________________
import numpy as np
import time
from joblib import Parallel, delayed
from numpy.random import uniform

N = 4

X = [uniform(-1, 1, [N,N,N,N]) for _ in range(8)]
        
def parallel():
    Parallel(n_jobs=8)(delayed(np.einsum)('pqrs,abcd,ijkl', X[i], X[i], X[i]) for i in range(8))
#End of Cell 1______________________________________________________________


#Start of Cell 2____________________________________________________________    
start = time.time()
parallel()
print(time.time() - start)
#End of Cell 2______________________________________________________________

问题背景

这段代码在命令行运行时耗时稳定在约2.5秒;拆分到Jupyter Notebook的两个单元格后,首次运行Cell 2耗时同样为2.5秒,但每次重运行Cell 2时,耗时稳定在1.8秒。针对以下问题解答:


1. 重运行加速是否属于预期现象?

是,完全符合预期。这种差异本质是首次运行需要完成初始化、编译或资源加载,后续运行可复用已准备好的资源,并非Jupyter本身的特殊BUG,而是计算框架和运行环境的正常优化逻辑。

2. 哪些场景会出现这类现象?

  • 数值计算库的编译/缓存优化:像np.einsum这类NumPy核心函数,首次调用时会触发底层BLAS/LAPACK后端的动态编译、运算规则解析与缓存;后续调用直接复用已编译好的执行逻辑,省去编译开销。
  • CPU缓存复用:首次计算后,数组数据或中间结果会被保留在CPU高速缓存(L1/L2/L3)中,后续计算无需从主内存重新读取,读写速度大幅提升。
  • 并行进程池复用:joblib.Parallel首次运行时需要创建8个工作进程,进程启动、环境初始化会消耗额外时间;重运行时直接复用已创建的进程池,省去进程启动的开销。
  • Jupyter内核状态保留:Jupyter内核会持续保留单元格运行后的变量、函数和已加载库的状态,首次运行后相关资源已加载完成,后续无需重复初始化。

3. 为什么time.sleep(1)无加速现象?

time.sleep是单纯的阻塞等待操作,不涉及任何数值计算、代码编译或内存缓存逻辑,也不会触发并行进程池的复用——每次调用都是单纯的等待,没有可复用的初始化资源或缓存成果,因此首次和重运行耗时完全一致。


内容的提问来源于stack exchange,提问作者Solarflare0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 17:53:15