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

为何NumPy中复数共轭运算速度与复数乘法相当?

复数共轭运算为何和复数乘法速度相当?

我对复数共轭运算速度接近复数乘法感到困惑,以下是测试代码和运行结果:

import numpy as np

def op0(x):
    return np.conj(x)
    
def op1(x0, x1):
    return x0 * x1
    
def op2(x0, x1):
    x0[:] = x1

for N in (50, 500, 5000):
    print(f"\nshape = ({N}, {N})")
    x0 = np.random.randn(N, N) + 1j*np.random.randn(N, N)
    x1 = np.random.randn(N, N) + 1j*np.random.randn(N, N)

    %timeit op0(x0)
    %timeit op1(x0, x1)
    %timeit op2(x0, x1)

运行结果:

shape = (50, 50)
3.55 µs ± 143 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
4.85 µs ± 261 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
1.85 µs ± 116 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

shape = (500, 500)
1.52 ms ± 60.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1.96 ms ± 133 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
299 µs ± 50.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

shape = (5000, 5000)
163 ms ± 4.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
185 ms ± 11.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
39.8 ms ± 399 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

为什么翻转x.imag的符号会这么耗时?从底层逻辑看,这明明比(a + j*b)*(c + j*d)这类包含多次乘法和加法的运算简单得多。

关键原因解析

  • 内存带宽是核心瓶颈:np.conj()默认会创建新数组,需要分配内存并复制所有数据(实部直接拷贝,虚部取反后拷贝)。复数乘法同样需要创建新数组并写入计算结果,两者的内存操作开销占比很高——对于大数组,内存读写的耗时远超过计算本身的差异,导致两者速度接近。
  • 硬件优化的差异:现代CPU有专门的SIMD指令优化复数乘法,能批量高效完成运算;而复数共轭的操作虽然简单,但对应的SIMD优化可能不够充分,或者内存开销掩盖了计算上的优势。
  • numpy实现路径:np.conj()的内部实现可能复用了通用的数组处理框架,没有针对“仅翻转虚部”做极致精简。对比原地赋值op2的速度,就能看出无计算的纯内存拷贝/修改要快得多,进一步说明内存操作是影响速度的关键。

环境:Windows 10 x64,numpy 1.23.5,Python 3.10.4

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:57:01