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

为什么NumPy中arr.mean()运行速度慢于arr.sum()/arr.size?

NumPy中ndarray.mean()性能低于sum()/size的原因

针对1D、2D整数NumPy数组的均值计算耗时测试代码与结果如下:

>>> setup = 'import numpy as np;a=np.random.randint(100, size=(100,100));b=np.random.randint(100, size=1000)'
>>> timeit.timeit(setup=setup, stmt='a.mean()')
13.513522000001103
>>> timeit.timeit(setup=setup, stmt='a.sum()/a.size')
6.080089200000657
>>> timeit.timeit(setup=setup, stmt='b.mean()')
5.404982399999426
>>> timeit.timeit(setup=setup, stmt='b.sum()/b.size')
2.261378399998648

造成这个稳定性能差异的核心原因有两个:

  • 累加器类型带来的开销差:测试用例全部为整数数组,直接调用sum()时,NumPy会默认使用与数组dtype匹配的整数累加器完成规约,整数累加的CPU指令执行效率更高,整个过程不需要对单个元素做类型转换,等全部整数累加完成后,仅需要做1次整数转浮点的标量除法(除以数组size)就能得到结果。而mean()为了避免整数除法精度损失、防止整数累加溢出导致结果错误,从规约阶段就会强制使用float64类型的累加器,每读取一个整数元素都要先完成一次整数转浮点的操作再参与累加,元素总量越大,这部分重复类型转换的开销占比越高。实际上手动执行a.sum(dtype=np.float64)/a.size,耗时会和a.mean()基本处于同一水平。
  • 通用接口的固定前置开销差:ndarray.mean()是覆盖全场景的通用规约接口,即使传入零参数计算全数组均值,内部也要完成axis参数校验、where掩码逻辑判断、keepdims维度规则匹配、dtype合法性检查、输出数组适配等一整套分支判断流程,这部分固定开销不随数组大小变化。而手写的sum()/size路径非常精简:sum()走无参数全数组规约的最优执行路径,size是数组对象初始化时就预存的内置属性,不需要遍历数组计算,最后一步标量除法的CPU开销可以忽略,整体前置开销远低于mean()。

补充说明:这个明显的性能差仅在整数数组场景下存在。如果测试对象是float32/float64类型的浮点数组,sum()默认也会使用浮点累加器,两者的性能差距会大幅缩小,基本只剩前置逻辑的开销差,处于同一量级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 09:33:28