Julia中大矩阵正方形子数组拆分的性能优化问询
Julia 大型二维数组正方形拆分的性能优化
原函数的性能瓶颈分析
- 使用
global变量存储结果数组,导致Julia无法进行类型推断,性能大幅下降 - 循环中反复调用
cat拼接数组,每次拼接都会重新分配内存并复制数据,随着结果数组增大,耗时呈线性增长 - 索引计算可以提前批量完成,避免循环内重复判断
优化方案一:手动预分配内存+批量索引计算
直接预先计算所有子数组的索引范围,一次性分配输出数组,再将每个子数组的内容填充进去,彻底避免动态拼接和全局变量带来的性能损耗:
function decimate_square_opt(data, fraction=4) sy, sx = size(data) square_side = Int(round(sy / fraction)) # 计算X方向的切片起始/结束位置 itersx = Int(floor(sx / square_side)) x_starts = vcat([square_side*(i-1)+1 for i in 1:itersx-1], sx - square_side + 1) x_ends = x_starts .+ square_side .- 1 # 计算Y方向的切片起始/结束位置 itersy = Int(floor(sy / square_side)) y_starts = vcat([square_side*(i-1)+1 for i in 1:itersy-1], sy - square_side + 1) y_ends = y_starts .+ square_side .- 1 # 预分配结果数组,提前锁定内存 num_squares = itersx * itersy dstack = similar(data, square_side, square_side, num_squares) # 批量填充子数组 idx = 1 for x_start in x_starts, y_start in y_starts dstack[:, :, idx] = data[y_start:y_start+square_side-1, x_start:x_start+square_side-1] idx += 1 end return dstack end
性能测试对比
测试代码:
using Random, Dates rand_arr = rand(1000, 32768) # 原函数性能测试 t1 = Dates.now() dec_arr_old = decimate_square(rand_arr) t2 = Dates.now() @info "原函数耗时: $(t2-t1)" # 优化后函数性能测试 t3 = Dates.now() dec_arr_new = decimate_square_opt(rand_arr) t4 = Dates.now() @info "优化后耗时: $(t4-t3)" # 验证结果一致性 @assert dec_arr_old == dec_arr_new
优化后的函数耗时通常能降到几百毫秒以内,性能提升可达几十倍。
优化方案二:使用视图避免数据复制(只读场景适用)
如果仅需要访问子数组而不需要复制数据,可以用@view宏创建数组视图,进一步节省内存和时间:
function decimate_square_views(data, fraction=4) sy, sx = size(data) square_side = Int(round(sy / fraction)) itersx = Int(floor(sx / square_side)) x_starts = vcat([square_side*(i-1)+1 for i in 1:itersx-1], sx - square_side + 1) itersy = Int(floor(sy / square_side)) y_starts = vcat([square_side*(i-1)+1 for i in 1:itersy-1], sy - square_side + 1) # 生成所有子数组的视图,无额外内存占用 return [@view data[y_start:y_start+square_side-1, x_start:x_start+square_side-1] for x_start in x_starts for y_start in y_starts] end
这个版本返回的是视图数组,访问速度极快,适合仅读取子数组的分析场景。
现成工具包参考
如果不想手动实现,可以参考ImageCore.jl中的数组切片工具,但对于这种特定的拆分需求,手动预分配的方式性能最优。
内容的提问来源于stack exchange,提问作者AaronJPung
相关产品推荐
相关产品推荐

