优化技巧 #
一、避免全局变量 #
1.1 问题 #
julia
global_var = 10
function use_global()
total = 0
for i in 1:10^6
total += global_var
end
return total
end
@time use_global()
1.2 解决方案 #
julia
function use_local(var)
total = 0
for i in 1:10^6
total += var
end
return total
end
@time use_local(10)
1.3 使用常量 #
julia
const CONST_VAR = 10
function use_const()
total = 0
for i in 1:10^6
total += CONST_VAR
end
return total
end
@time use_const()
二、预分配 #
2.1 问题 #
julia
function grow_array(n)
arr = Int[]
for i in 1:n
push!(arr, i)
end
return arr
end
@time grow_array(10^6)
2.2 解决方案 #
julia
function preallocate(n)
arr = Vector{Int}(undef, n)
for i in 1:n
arr[i] = i
end
return arr
end
@time preallocate(10^6)
2.3 使用sizehint! #
julia
function with_sizehint(n)
arr = Int[]
sizehint!(arr, n)
for i in 1:n
push!(arr, i)
end
return arr
end
三、类型稳定性 #
3.1 问题 #
julia
function unstable(x)
if x > 0
return x
else
return 0.0
end
end
@code_warntype unstable(1)
3.2 解决方案 #
julia
function stable(x::T) where {T<:Real}
if x > 0
return T(x)
else
return zero(T)
end
end
@code_warntype stable(1)
四、循环优化 #
4.1 避免边界检查 #
julia
function with_bounds_check(arr)
total = 0.0
for i in 1:length(arr)
total += arr[i]
end
return total
end
function without_bounds_check(arr)
total = 0.0
@inbounds for i in 1:length(arr)
total += arr[i]
end
return total
end
arr = rand(10^6)
@time with_bounds_check(arr)
@time without_bounds_check(arr)
4.2 使用@simd #
julia
function regular_sum(arr)
total = 0.0
for x in arr
total += x
end
return total
end
function simd_sum(arr)
total = 0.0
@simd for x in arr
total += x
end
return total
end
arr = rand(10^6)
@time regular_sum(arr)
@time simd_sum(arr)
4.3 列优先访问 #
julia
function row_major(mat)
total = 0.0
for i in 1:size(mat, 1)
for j in 1:size(mat, 2)
total += mat[i, j]
end
end
return total
end
function col_major(mat)
total = 0.0
for j in 1:size(mat, 2)
for i in 1:size(mat, 1)
total += mat[i, j]
end
end
return total
end
mat = rand(1000, 1000)
@time row_major(mat)
@time col_major(mat)
五、避免分配 #
5.1 使用广播 #
julia
function with_allocation(arr)
arr .+ 1
end
function without_allocation!(arr)
arr .+= 1
end
arr = rand(10^6)
@time with_allocation(arr)
@time without_allocation!(arr)
5.2 使用预分配结果 #
julia
function compute!(result, a, b)
result .= a .+ b
end
a = rand(10^6)
b = rand(10^6)
result = similar(a)
@time compute!(result, a, b)
六、实践练习 #
6.1 练习1:优化求和 #
julia
function slow_sum(arr)
total = 0
for x in arr
total += x
end
return total
end
function fast_sum(arr)
total = zero(eltype(arr))
@inbounds @simd for x in arr
total += x
end
return total
end
arr = rand(10^6)
@time slow_sum(arr)
@time fast_sum(arr)
6.2 练习2:优化矩阵乘法 #
julia
function slow_matmul(A, B)
C = zeros(size(A, 1), size(B, 2))
for i in 1:size(A, 1)
for j in 1:size(B, 2)
for k in 1:size(A, 2)
C[i, j] += A[i, k] * B[k, j]
end
end
end
return C
end
function fast_matmul(A, B)
C = zeros(size(A, 1), size(B, 2))
@inbounds for i in 1:size(A, 1)
for k in 1:size(A, 2)
for j in 1:size(B, 2)
C[i, j] += A[i, k] * B[k, j]
end
end
end
return C
end
A = rand(100, 100)
B = rand(100, 100)
@time slow_matmul(A, B)
@time fast_matmul(A, B)
6.3 练习3:优化字符串处理 #
julia
function slow_concat(n)
s = ""
for i in 1:n
s *= string(i)
end
return s
end
function fast_concat(n)
parts = String[]
for i in 1:n
push!(parts, string(i))
end
return join(parts)
end
@time slow_concat(1000)
@time fast_concat(1000)
七、总结 #
本章我们学习了:
- 避免全局变量:使用局部变量和常量
- 预分配:避免动态增长
- 类型稳定性:保持类型一致
- 循环优化:@inbounds、@simd、列优先
- 避免分配:广播和预分配结果
接下来让我们学习Julia的类型稳定性!
最后更新:2026-03-27