Could you give more details on the @btime
error? I can’t reproduce using the code you posted above and running @btime create_FoodWeb(BM, Ropt,γ)
That said the suggestions given above help quite a bit with performance, the following slightly simplified version gives benchmark results between 1 and 15 seconds (trials are quite variable maybe due to the randomness in the while
condition?)
I’ve added some comments as I’m not 100% sure my simplifications haven’t accidentally changed your algorithm, so do double check!
using Distributions, Random, BenchmarkTools
# note BM is not required as an input to this function
# Julia convention is to only capitalise types, not variable names
function create_foodWeb(Ropt, γ, no_plant, no_animal)
function create_L(bm, Ropt, γ, no_plant)
x = (bm ./ (bm' .* Ropt))'
L = @. ( x * exp(1.0 - x) )^γ
L[:, 1:no_plant] .= 0.0
L[L .<= 0.01] .= 0.0
return L # return is a keyword rather than a function
end
# preallocating arrays
foodWeb = zeros(no_plant + no_animal, no_plant + no_animal)
L = zeros(size(foodWeb)...)
bm = zeros(no_plant + no_animal)
condition = true
while condition
# assigning directly rather than creating new BM_A/BM_P arrays and vcating
bm[1:no_plant] = sort(rand(Uniform(10^0, 10^6), no_plant))
bm[no_plant+1:end] = sort(rand(Uniform(10^2, 10^12), no_animal))
L = create_L(bm, Ropt, γ, no_plant)
foodWeb .= 0.0 # setting existing array to zero
foodWeb[L .> rand()] .= 1.0 # note rand() already samples from Uniform(0,1)
# removed the x->x>0 as entries in foodWeb are either 0 or 1 anyway
condition = any(sum(foodWeb, dims=1) + sum(foodWeb, dims=2)' .== 0.0)
end
return bm, L, foodWeb
end
Ropt = 100
γ = 2
no_plant = 8
no_animal = 12
@benchmark create_foodWeb(Ropt, γ, no_plant, no_animal)