Julia广播操作较for循环内存开销高且test3返回错误原因问询
test3返回错误结果的原因
Julia中对数组做普通切片操作(如A[k+1:n, k])时,默认会返回原数组对应片段的拷贝,而非指向原数组的视图。
你在test3中调用broadcast!时,第一个参数传入的是A[k+1:n, k]生成的临时拷贝数组,运算结果只会写入这个临时拷贝对象,不会同步修改原数组A,循环结束后原数组几乎没有改动,因此返回结果错误。同时每次循环会额外生成输入切片和输出切片两份临时拷贝,因此内存开销是test2的两倍。
广播操作内存开销远高于普通for循环的原因
普通for循环中直接通过A[i, k]索引原数组,不需要生成任何中间临时对象,因此全程零堆内存分配。
而test2中使用A[k+1:n, k] ./= A[k,k]时,默认生成A[k+1:n, k]的拷贝作为广播操作的输入临时数组,每轮循环都会产生一次堆内存分配,累积下来总内存开销就远高于无临时分配的普通for循环。
要实现和for循环一致的零分配广播,只需要给切片加上@view宏生成视图即可,修改后的写法如下:
function test2_opt(A) n = size(A, 2) for k in 1:n @view(A[k+1:n, k]) ./= A[k,k] end A end
该版本的@allocated返回值和test1一致为0,性能完全对齐手写for循环。
广播操作的官方使用规范说明
官方文档明确了广播的正确使用规则:
- 点广播语法默认会尝试就地执行运算,仅当输入/输出参数存在临时拷贝时才会产生额外分配
- 普通切片默认返回拷贝,要避免临时分配需要显式使用
@view(单个切片)或@views(作用域内所有切片自动转视图)宏生成数组视图 - 手动调用
broadcast!时,必须保证第一个目标参数是指向原存储的可变视图,否则运算结果不会写入原数组
内容的提问来源于stack exchange,提问作者Paul Dydyshko
相关产品推荐
相关产品推荐

