Hi. I’m currently experiencing a bottleneck in my simulations where a relatively large amount of time is spent on the setindex!
function from DataStructures.jl
’s implementation of a priority queue. I have a representation of a cell and a priority queue to hold reactions on the basis of when they will occur, and I update elements of this queue at the end of each step. I have included a very simple form of my simulation: the main function here is updatePriority
. This function loops over the range of reactions, checks if a reaction is possible and then updates the priority of that reaction. Are there any implementations of a priority queue in Julia, or any data structure that can operate as one, that allows more efficient updates with O(1) lookup for the minimum? My priority queue will never change in size: once the reactions are queued up, they will only ever have their priorities changed so I’m willing to trade efficiency in insertions/deletions in exchange for faster updates. I’m also wondering where so much of the memory allocations in my benchmark is coming from: if I am updating 34 64 bit floating point values 100,000 times that comes to around 27.2MiB of memory but I allocate almost 6x that amount.
using DataStructures
using Distributions
struct HexCell
# Representation of a cell.
propensity::Array{Float64}
internalTime::Array{Float64}
fireTime::Array{Float64}
pQueue::PriorityQueue{Int,Float64}
end
function updatePriority(cell::HexCell)
# Either set the time step for each of the 34 reactions to some value,
# or to Inf. The primary function to benchmark.
for i in 1:34
cell.pQueue[i] = cell.propensity[i] > 0 ? (cell.fireTime[i]-cell.internalTime[i])/cell.propensity[i] : Inf
end
end
function initialize()
# Construct the cell and enqueue all of the reactions.
cell = HexCell(rand(Uniform(-1,1), 34),
rand(Uniform(0,1), 34),
rand(Uniform(0,1), 34),
PriorityQueue{Int,Float64}())
for i in 1:34
delT = cell.propensity[i] > 0 ? (cell.fireTime[i]-cell.internalTime[i])/cell.propensity[i] : Inf
enqueue!(cell.pQueue, i, delT)
end
return cell
end
function simulate(cell::HexCell)
for i in 1:100_000
updatePriority(cell)
end
end
Here are some benchmarks for the simulation.
julia> c = initialize()
julia> @benchmark simulate(c)
BenchmarkTools.Trial:
memory estimate: 172.42 MiB
allocs estimate: 11300000
--------------
minimum time: 384.554 ms (1.11% GC)
median time: 389.894 ms (1.59% GC)
mean time: 390.395 ms (1.72% GC)
maximum time: 398.028 ms (1.98% GC)
--------------
samples: 13
evals/sample: 1
Thanks in advance!