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

优化O(n²)复杂度的Julia代码,提升仿真计算效率

Julia核心计算代码进一步优化请求

背景

我正在开发一款时间复杂度为O(n²)的仿真程序,主体基于Python,为提升性能将核心计算卸载至Julia。每次仿真迭代需对比100个实例,共产生4900次比较:Python实现耗时约63秒,Julia初始实现耗时降至30秒。这是我首次编写Julia代码,认为仍有优化空间,现寻求改进方案。

calculate_novelty由Python脚本调用,histograms是包含100个20×20矩阵的向量。

初始Julia代码

using Shuffle

function apply_noise_mask(hist, INT_CASTER::UInt)
    diff::UInt = INT_CASTER - sum(hist)

    mask = zeros(UInt, size(hist))
    mask = shuffle(replace(mask, 0=>1, count=diff))
    return hist + mask
end

function move_supply(supply, fcoord::CartesianIndex , capacity, tcoord::CartesianIndex, INT_CASTER::UInt)
    if supply[fcoord] <= capacity[tcoord]
        flow = supply[fcoord]
        capacity[tcoord] -= flow
        supply[fcoord]= 0
    else
        flow = capacity[tcoord]
        supply[fcoord] -= flow
        capacity[tcoord] = 0
    end
    distance = sqrt(abs(fcoord[1]-tcoord[1])^2 + abs(fcoord[2]-tcoord[2])^2)
    score = flow/INT_CASTER*distance
    return score, supply, capacity
end

function wasserstein_distance(hist0, hist1, INT_CASTER::UInt)::Float16
    supply, capacity = trunc.(UInt, hist0.*INT_CASTER), trunc.(UInt, hist1.*INT_CASTER)
    supply, capacity = apply_noise_mask(supply, INT_CASTER), apply_noise_mask(capacity, INT_CASTER)

    score::Float16 = 0
    while true
        from_idx, to_idx = findfirst(supply .> 0), findfirst(capacity .> 0)

        if (from_idx == nothing) || (to_idx == nothing)
            return score
        end
        work, supply, capacity = move_supply(supply, from_idx, capacity, to_idx, INT_CASTER)
        score += work
    end
end

function calculate_novelty(histograms)
    @time begin

        INT_CASTER::UInt = 10000
        amt_instances::UInt = length(histograms) # population = 100 -> int8 goes until 127

        novelty_scores = zeros(Float16, amt_instances)
        for i = 1:amt_instances-1
            for j = 1+i:amt_instances
                score = wasserstein_distance(histograms[i], histograms[j], INT_CASTER)
                novelty_scores[i] += score
                novelty_scores[j] += score
            end
        end
    end
    return novelty_scores
end

初始运行性能

15.760257 seconds (20.87 M allocations: 28.901 GiB, 11.97% gc time)
15.592724 seconds (20.72 M allocations: 28.697 GiB, 11.95% gc time)

Julia版本:1.8

已完成的优化及效果

替换findfirst为自定义遍历函数

function find_first_candidate(arr)
    for elem in CartesianIndices(arr)
       if arr[elem] > 0
          return elem
        end
    end
    return nothing
end

优化后平均运行耗时:

1.095999 seconds (99.02 k allocations: 314.210 MiB, 1.74% gc time)

采用原地修改函数

进一步减少内存分配后,平均运行耗时:

1.090733 seconds (59.41 k allocations: 188.528 MiB, 1.70% gc time)

寻求进一步优化方案

现希望得到更多针对该Julia代码的优化建议,以进一步提升性能。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 15:15:25