【发布时间】:2015-04-07 20:31:21
【问题描述】:
在 ruby 中计算数组 x 秒滚动平均值的最快方法是什么?
我有两个骑自行车的数据数组。该时间是在行驶过程中读取相应速度值的时间。您会注意到读数并不是每秒都读取的。出于这个原因,我不相信我可以将滚动数组加一。
speed = [0, 15, 17, 19, 18, 22, 24, 28, 22, 17, 16, 14, 15, 15, 15, 0, 15, 19, 21, 25, 26, 24, 24]
time = [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 20, 21, 22, 23, 25, 26, 27]
我已经尝试过类似以下的方法(计算 5 秒的滚动平均值并将其放入一个数组中),但对于大型数组和多个间隔来说它非常慢(需要 8 分钟来计算 1 小时自行车骑行的所有间隔, 1..3600):
duration = time.max
interval_average = []
time_hash = Hash[time.map.with_index.to_a]
roll_start = 0
roll_stop = 5
for i in 1..(duration+1) do
start = time_hash[roll_start]
stop = time_hash[roll_stop]
rolling_array = speed[start..stop]
avg_value = mean(rolling_array)
interval_average.push(avg_value)
roll_start += 1
roll_stop += 1
end
在我自己的代码中,我忽略了异常并改为推送 0,因为我真的只是对最终找到 x 秒平均值的最大值感兴趣。
【问题讨论】:
-
speed[start..stop]将分配一个子数组,这可能会导致一些实质性的 GC 抖动。您的目标可能应该是尽可能消除分配;重用中间数组将产生巨大的好处。 -
@ChrisHeald 我怀疑分配是这里的罪魁祸首。
arr = 10_000_000.times.to_a; Benchmark.measure { 1_000_000.times { ar[100..-2] } }.real #=> 0.17680915212258697 -
首先分析您的代码以查看时间的去向(例如 ruby-prof)