# Benchmarking slow agents.jl code

**URL:** <https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871>\
**Category:** Modelling & Simulations\
**Tags:** agents\
**Created:** [June 14, 2025, 1:41am UTC](https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871 "2025-06-14T01:41:35Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![geoffdougherty](https://avatars.discourse-cdn.com/v4/letter/g/9de053/32.png) [@geoffdougherty](https://discourse.julialang.org/u/geoffdougherty)\
**Post date:** [June 14, 2025, 1:41am UTC](https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871/1 "2025-06-14T01:41:35Z")

</div>

Hi, all. I am relatively new to Agents.jl and am noticing that my model is running quite slowly compared to similar models using other platforms. Following the performance advice in the Agents.jl documentation, I’d like to use BenchmarkTools to profile several chunks of code within the agent\_step and model\_step functions.

However, it’s not immediately clear to me how to do this. The BenchmarkTools documentation seems to focus on setting the benchmark immediately prior to the function of interest. However, my agent\_step function doesn’t contain other functions – it’s procedural code (if x do a, b and c. If y, do d, e and f). I am wondering if there’s a way to benchmark sections of this type of procedural code. Thanks!

---

<div class="post-metadata">

**Author:** ![karei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karei/32/214809_2.png) [@karei](https://discourse.julialang.org/u/karei)\
**Post date:** [June 14, 2025, 2:46am UTC](https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871/2 "2025-06-14T02:46:47Z")

</div>

> **[GitHub - KristofferC/TimerOutputs.jl: Formatted output of timed sections in Julia](https://github.com/KristofferC/TimerOutputs.jl)**
>
> Formatted output of timed sections in Julia

For example:

```julia
using TimerOutputs
const to = TimerOutput()
function time_test()
    @timeit to "nest 1" begin
        # put your first code segment here
    end
    @timeit to "nest 2" begin
        # put your second code segment here
    end
end

for _ = 1:100 # set to large number to get more accurate result
    time_test()
end

reset_timer!(to) # reset

```

---

<div class="post-metadata">

**Author:** ![geoffdougherty](https://avatars.discourse-cdn.com/v4/letter/g/9de053/32.png) [@geoffdougherty](https://discourse.julialang.org/u/geoffdougherty)\
**Post date:** [June 16, 2025, 2:17pm UTC](https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871/3 "2025-06-16T14:17:26Z")

</div>

Thanks for this, the approach is very helpful and TimerOutputs looks cool! I ended up going with a slightly different approach, because the code I’d like to time is called by another series of functions. Here’s what I have now:

```julia
function agent_step!(agent, model)
    t = @elapsed begin
      # step code for agents 
    end 
   # capture the elapsed time for this step and increment the time tracker 
   model.agentStepTotalTime += t
end

```

I am running similar code for the model\_step function. My idea is to get a sense of the overall elapsed time for each, and then dig into subsections of those two functions using @elapsed.

However, I am noticing that my total run time for 1,000 steps of the model is exponentially longer than the cumulative run time for agent\_step and model\_step. This is confusing to me, because these two functions seem to be the only code that runs for each model step, and the only other code that runs at all is model initialization.

Anyone have thoughts on what might be going on here or how to further debug?

Thanks!

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [June 16, 2025, 4:23pm UTC](https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871/4 "2025-06-16T16:23:56Z")

</div>

One way to profile your code is calling the stepping function with the `Profile` library, see [Profiling · The Julia Language](https://docs.julialang.org/en/v1/manual/profile/). It should be as simple as

```julia
julia> using Profile

julia> step!(model, 1) # compile

julia> @profile step!(model, n)

julia> Profile.print()

```

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [June 16, 2025, 6:08pm UTC](https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871/5 "2025-06-16T18:08:35Z")

</div>

> [@geoffdougherty](#):
>
> I am noticing that my total run time for 1,000 steps of the model is exponentially longer than the cumulative run time for agent\_step and model\_step. This is confusing to me, because these two functions seem to be the only code that runs for each model step, and the only other code that runs at all is model initialization.

It’s hard to say without seeing the code, but that sounds like it might be a type inference/type instability problem. `@code_warntype` on the model might help check if this is the case. Cthulhu.jl could help in trickier cases.

---

<div class="post-metadata">

**Author:** ![geoffdougherty](https://avatars.discourse-cdn.com/v4/letter/g/9de053/32.png) [@geoffdougherty](https://discourse.julialang.org/u/geoffdougherty)\
**Post date:** [June 16, 2025, 6:22pm UTC](https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871/6 "2025-06-16T18:22:17Z")

</div>

Thanks, I will give this a look. The other thing I am noticing is that running the model for additional steps creates an massive increase in run time. i.e., run!(model, 200) creates a run time that is equal to run!(model, 100) to the fifth power or something. I am watching CPU and RAM usage as this is happening and not seeing anything crazy.

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [June 16, 2025, 6:28pm UTC](https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871/7 "2025-06-16T18:28:42Z")

</div>

I think you need to create a MWE and present it here because this doesn’t sound like normal Agents.jl usage. Running the model twice as long should take exactly twice the time.

---

<div class="post-metadata">

**Author:** ![geoffdougherty](https://avatars.discourse-cdn.com/v4/letter/g/9de053/32.png) [@geoffdougherty](https://discourse.julialang.org/u/geoffdougherty)\
**Post date:** [July 7, 2025, 7:39pm UTC](https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871/8 "2025-07-07T19:39:29Z")

</div>

Hi, the whole model is a ton of code, but the agent\_step file is here:

> <https://gist.github.com/geoffdougherty1/2c02aa03e19f2657127668d8e31dc8be>

After working with this a bit, it seems there is significant variability in the duration of model runs with the same step count. It also appears that this coincides with agents taking more steps to work their way through the process (medical care) that I’m modeling. I suspect understanding this might help with reducing model run time, so I’d like to execute a couple hundred runs or so and collect statistics on agent and run times. I haven’t seen a way to do this in the documentation, so suggestions would be helpful.

After running with @codewarn\_type, it looks like switching from Union to @multiagent would potentially help, so I will work on that. I also have some untyped Dict items to fix.

---

<div class="post-metadata">

**Author:** ![geoffdougherty](https://avatars.discourse-cdn.com/v4/letter/g/9de053/32.png) [@geoffdougherty](https://discourse.julialang.org/u/geoffdougherty)\
**Post date:** [July 9, 2025, 1:52am UTC](https://discourse.julialang.org/t/benchmarking-slow-agents-jl-code/129871/9 "2025-07-09T01:52:08Z")

</div>

I stumbled across ensemblerun!, which is helpful. Additionally, switching from a dictionary to struct for model parameters seemed to boost performance quite a bit.
