Optimization 为什么我的移动平均算法这么慢?

Optimization 为什么我的移动平均算法这么慢?,optimization,fortran,moving-average,Optimization,Fortran,Moving Average,我编写了一个Fortran函数,它以非常简单的方式计算一维数字数组的移动平均值: function moving_average(data, w) implicit none integer, intent(in) :: w real(8), intent(in) :: data(:) integer :: n, i real(8) :: moving_average(size(data)-w+1) n = w-1 do i=1,

我编写了一个Fortran函数,它以非常简单的方式计算一维数字数组的移动平均值:

function moving_average(data, w)

    implicit none

    integer, intent(in) :: w
    real(8), intent(in) :: data(:)

    integer :: n, i
    real(8) :: moving_average(size(data)-w+1)

    n = w-1

    do i=1, size(data)-n
        moving_average(i) = mean(data(i:i+n))
    end do

end function
其中函数
平均值
定义为:

real(8) function mean(data)

    implicit none

    real(8), dimension(:), intent(in) :: data

    mean = sum(data)/size(data)

end function

在数据集为100000个数字、窗口宽度为1000的笔记本电脑上运行函数
moving_average
,需要0.1秒。但是,在使用
numpy
时运行函数
仅需1 ms。为什么我的算法要慢得多?

您的算法的阶数为O(n*m),n为移动平均值的大小,m为数组的大小

每次计算阵列中的点时,都要执行以下步骤:

  • 提取数组的一部分
  • 计算该切片上的和
  • 除以常数
    n
然而,
移动平均值(i)
移动平均值(i+1)
的关联方式如下:

moving_average(i+i) = moving_average(i) + (data(i+n) - data(i-1))/n

当您使用此选项时,您可以将计算时间从O(n*m)减少到O(m)

real(8)很难看,而且不是portable@VladimirF你有什么建议?使用
selected\u real\u kind
?命名常量。若它必须等于8,那个就这样吧,但选择真实种类更好。或者尝试
iso_fortran_env
,比如
仅使用iso_fortran_env:real64;real(real64)::数据(:)
。fortran标准的
iso\u fortran\u env
中至少定义了以下类型:
int8
int16
int32
int64
real32
real64
real128