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

使用Views进行内存分配:Julia切片性能优化疑问

Julia切片与@views性能优化问题

测试代码

using Distributions
using BenchmarkTools

u = randn(100, 2)
res = ones(100)
idx = 1
u_vector = u[:, idx]

@btime $res = $1.0 .- $u_vector;
@btime $res = $1.0 .- $u[:,idx];
@btime @views $res = $1.0 .- $u[:,idx];

运行结果

julia> @btime $res = $1.0 .- $u_vector;
  37.478 ns (1 allocation: 896 bytes)

julia> @btime $res = $1.0 .- $u[:,idx];
  607.383 ns (13 allocations: 1.97 KiB)

julia> @btime @views $res = $1.0 .- $u[:,idx];
  397.597 ns (6 allocations: 1.08 KiB)

问题分析与优化方案

为什么@views版本性能不如第一条?

@views确实避免了切片时创建副本,生成的是SubArray视图,但广播操作对SubArray的处理效率远低于原生Vector:

  • SubArray需要额外的索引映射计算,无法像原生数组那样直接连续访问内存;
  • Julia的广播优化逻辑对原生数组更友好,针对SubArray的广播会产生额外开销;
  • 原代码三条语句都是重新赋值res,即生成新数组再覆盖res,SubArray的广播生成新数组的过程本身就比原生Vector慢。

优化方案(无额外内存分配)

既然res已经预先分配好内存,应该原地修改res的元素,而非重新生成数组赋值,这样能彻底消除内存分配,同时适配动态变化的idx:

方案1:利用广播原地赋值

@btime @. res = 1.0 - @views u[:, idx];

方案2:手动循环(适配更复杂计算场景)

@btime begin
    @inbounds for i in eachindex(res)
        res[i] = 1.0 - u[i, idx]
    end
end

两种写法都能实现0内存分配,性能接近第一条原生Vector的水平。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 00:05:32