# Debugging extremely slow

**URL:** <https://discourse.julialang.org/t/debugging-extremely-slow/53801>\
**Category:** Tooling\
**Tags:** question\
**Created:** [January 22, 2021, 7:18pm UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801 "2021-01-22T19:18:00Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 10, 2023, 9:06pm UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/21 "2023-04-10T21:06:01Z")

</div>

Why are you using a debugger in the first place? If you write small functions, test them using unit test and use them to assemble larger functions you will never need a debugger…

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 10, 2023, 10:00pm UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/22 "2023-04-10T22:00:44Z")

</div>

> [@ufechner7](#):
>
> Why are you using a debugger in the first place?

Not this again. You need debuggers to understand how code works and what it is doing.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 11, 2023, 2:47am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/23 "2023-04-11T02:47:33Z")

</div>

Well, if I want to understand a specific piece of code I copy it line by line in the REPL and inspect the intermediate results…

---

<div class="post-metadata">

**Author:** ![fmvin](https://avatars.discourse-cdn.com/v4/letter/f/b38774/32.png) [@fmvin](https://discourse.julialang.org/u/fmvin)\
**Post date:** [April 11, 2023, 3:54am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/24 "2023-04-11T03:54:24Z")

</div>

The talk in the way “don’t use the debugger because it’s not properly working” doesn’t make sense.  
In the first place, lack of a fast, robust debugging tool prevents professional researchers/developers around me from moving from matlab to Julia. Development on Julia is simply more expensive.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 11, 2023, 4:57am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/25 "2023-04-11T04:57:06Z")

</div>

> [@ufechner7](#):
>
> I copy it line by line in the REPL

How is this better? And how do you step-in and step-out of functions? How do you handle loops? You can’t copy half a loop without getting syntax errors. How do you handle scoping issues?

How is this even remotely as good as a debugger?

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [April 11, 2023, 11:30am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/26 "2023-04-11T11:30:09Z")

</div>

From the standpoint of JuliaInterpreter performance, at present the only real solution is to `push!` more modules or methods onto `JuliaInterpreter.compiled_modules` or `JuliaInterpreter.compiled_methods`, respectively. While I demoed that above for `Base` modules ([Debugging in Juno extremely slow - #4 by tim.holy](https://discourse.julialang.org/t/debugging-in-juno-extremely-slow/53801/4)), this doesn’t have to be limited to `Base`, you can also push package modules, too.

The other alternative is to use something besides the debugger, like `@show` statements with Revise, Infiltrator, etc.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [April 11, 2023, 11:33am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/27 "2023-04-11T11:33:31Z")

</div>

FWIW, there are some utilities for mutating `compiled_modules`/`compiled_methods` in VS Code, so you might want to give the debugger there a go.  
We’re running all Base methods in compiled mode (except for a sadly incomplete list of higher order functions that need to be interpreted) and there’s a special `ALL_MODULES_EXCEPT_MAIN` token that runs every method not defined in Main in compiled mode.

---

<div class="post-metadata">

**Author:** ![fmvin](https://avatars.discourse-cdn.com/v4/letter/f/b38774/32.png) [@fmvin](https://discourse.julialang.org/u/fmvin)\
**Post date:** [April 11, 2023, 6:41pm UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/29 "2023-04-11T18:41:08Z")

</div>

Thanks a lot. After putting `ALL_MODULES_EXCEPT_MAIN` into `settings.json` the debugger takes about 23 sec for reaching a first line of own code. It’s better than ~30 sec.

---

<div class="post-metadata">

**Author:** ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)\
**Post date:** [April 11, 2023, 11:54pm UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/30 "2023-04-11T23:54:28Z")

</div>

If you’ve already got a REPL in VS code open, with most things compiled and the main packages on the compiled modules list, then using `@enter` to step into a function usually only takes a couple of seconds and is usually much faster than debugging in a new process. For example:

```julia
using Revise
includet("main.jl") # defines a `main` function
@enter main()

```

This also helps if loading/creating objects is costly but not what you want to debug as you generate once and pass into the function and modify the code and continue to debug until it works.

---

<div class="post-metadata">

**Author:** ![fmvin](https://avatars.discourse-cdn.com/v4/letter/f/b38774/32.png) [@fmvin](https://discourse.julialang.org/u/fmvin)\
**Post date:** [April 12, 2023, 8:51am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/31 "2023-04-12T08:51:02Z")

</div>

Anyway, 23 sec to start a debugger is very slow obviously.  
I have tested some script without Makie (without charting at all) in the same env `ALL_MODULES_EXCEPT_MAIN` and got ~13 sec. It is not fast either.

Are such dalays normal? Or may be something wrong with my environment and could be adjusted.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [April 12, 2023, 9:42am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/32 "2023-04-12T09:42:48Z")

</div>

I’d recommend following @jmair’s suggestion, which should cut down on the overhead by a lot.

---

<div class="post-metadata">

**Author:** ![fmvin](https://avatars.discourse-cdn.com/v4/letter/f/b38774/32.png) [@fmvin](https://discourse.julialang.org/u/fmvin)\
**Post date:** [April 12, 2023, 10:51am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/33 "2023-04-12T10:51:21Z")

</div>

@jmair’s suggestion really helps. Debugger starts on second and next tries immediately. Breakpoints work.  
Thanks a lot.

---

<div class="post-metadata">

**Author:** ![Soldalma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/soldalma/32/29388_2.png) [@Soldalma](https://discourse.julialang.org/u/Soldalma)\
**Post date:** [June 5, 2023, 9:45am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/34 "2023-06-05T09:45:12Z")

</div>

Could you show a beginner how does one push package modules?

---

<div class="post-metadata">

**Author:** ![Soldalma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/soldalma/32/29388_2.png) [@Soldalma](https://discourse.julialang.org/u/Soldalma)\
**Post date:** [June 5, 2023, 9:48am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/35 "2023-06-05T09:48:53Z")

</div>

How would it work if the function foo() is already defined in a package MyPackage I created? Do I have to includet a copy of it saved to a file? Can I just paste the function definition in the REPL? Would I have to do @enter MyPackage.foo()?

---

<div class="post-metadata">

**Author:** ![Soldalma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/soldalma/32/29388_2.png) [@Soldalma](https://discourse.julialang.org/u/Soldalma)\
**Post date:** [June 5, 2023, 9:57am UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/36 "2023-06-05T09:57:24Z")

</div>

In my experience the slow speed of debugging is a problem for Julia. I could not make it faster. There are no detailed examples anywhere. The people who suggest solutions are very knowledgeable and do not seem to understand the predicament of a beginner. Step by step instructions on how to make debugging faster is what is needed.

I created my own solution, which works except that I cannot go up and down in the stack. Just before a function is called I serialize the arguments that will be passed to it, then stop the program with error, then go to the REPL, deserialize the variables and manually run the code in the function’s body. That works, and is better than Infiltrator because: 1) I can do literally anything, even rewrite the whole function body, 2) I can run the program in the VSCode REPL, which cannot be done in Infiltrator.

I am not even a programmer. People more knowledgeable should be able to improve on what is below.

These are instructions:

```julia
# If the function foo(modeldata, df_xr, data, parameter, ctrl_parms)
# is called with arguments (modeldata, df_xray, precalc_data, parameter, ctrl_parms)

# insert the following just before the function call:

d_symbs = Dict(
	:modeldata => modeldata,
	:df_xr => df_xray,
	:data => precalc_data,
	:parameter => parameter,
	:ctrl_parms => ctrl_parms
)

# You can use another path if you wish
debug_path = "C:\\Users\\fsald\\Dropbox\\Temp\\dsymbs.srlz"

serialize(debug_path, d_symbs)

error("\n*&*&*&*&*&*&*&*&*&*&*& STOP HERE\n") 

# Then go to the REPL and call

deserialize_symbs(debug_path)

# After that you can run the code in foo, alter it as you wish etc.

The function deserialize_symbs is below. It must be run in the top level. Otherwise one would have to put the module name and a dot before each variable name. For example, it it was defined in module M one would have to write M.modeldata instead of just modeldata.

#@deserialize_symbs
"""
    deserialize_symbs(
        path = "C:\\Users\\fsald\\Dropbox\\Temp\\Symbs.srlz"
    ):Nothing

Deserializes a dictionary whose keys are symbols and whose names are any
values. Then assigns the values to the names corresponding to the symbols.

# Arguments
- `path`: the path where the dictionary has been serialized.

# Example
julia> debug_path = "C:\\Users\\fsald\\Dropbox\\Temp\\debug.srlz"
d = [:x => 1, :y => "W"]
serialize(debug_path, d)
x = 999 # changed the value of x
deserialize_symbs(debug_path)
x == 1 # true, x now has the value that was deserialized

Last Edited: 2023-05-31
"""
function deserialize_symbs(path::String):Nothing
    d_symbs = deserialize(path)
    for (symb, v) in d_symbs
        @eval(($symb) = ($v))
    end
end # deserialize_symbs

```

---

<div class="post-metadata">

**Author:** ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)\
**Post date:** [June 5, 2023, 1:48pm UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/37 "2023-06-05T13:48:19Z")

</div>

If you are working with a package:

```julia
julia> using MyPackage # exports myfunc()
julia> using Revise
julia> Revise.track(MyPackage)
julia> @enter myfunc()
julia> @enter MyPackage.myfunc() # alternative

```

This usually works for me, but not 100% perfect. Debugging in Julia isn’t as nice a experience as in other languages (e.g. C# in VS), but this is a tradeoff with having a very good REPL based workflow instead.

P.s. Try to make sure you add the heavy packages to the compiled modules (can be done through VS code Julia panel - usually on the bottom left - e.g. `CUDA.*`) to make sure debugging is fast enough to be useable.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [June 5, 2023, 2:01pm UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/38 "2023-06-05T14:01:28Z")

</div>

`push!(JuliaInterpreter.compiled_modules, Base)`. Do this before you start debugging. You can add packages to this, too: `push!(JuliaInterpreter.compiled_modules, SomePackage)`. If you want to be more comprehensive and include inner modules, you can do this:

```julia
using JuliaInterpeter, MethodAnalysis
union!(JuliaInterpreter.compiled_modules, child_modules(Base))

```

This adds an additional 44 modules that are inside `Base`, so that all of Julia’s own code will be run in compiled mode. This should give you an experience that’s a little closer to what you’d get in Matlab or Python, where the internal code is mostly in C and can’t be interpreted.

---

<div class="post-metadata">

**Author:** ![Soldalma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/soldalma/32/29388_2.png) [@Soldalma](https://discourse.julialang.org/u/Soldalma)\
**Post date:** [June 5, 2023, 3:38pm UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/39 "2023-06-05T15:38:58Z")

</div>

Thanks. Very helpful.

Just to clarify, adding the child modules of Base seems to add more code to the list that is run in compiled mode. So should I do the following? Or is the second line not needed given that the third line will be executed?

```julia
using JuliaInterpreter, MehodAnalysis
push!(JuliaInterpreter.compiled_modules, Base)
union!(JuliaInterpreter.compiled_modules, child_modules(Base))
push!(JuliaInterpreter.compiled_modules, MyPackage)

```

How does this compare with clicking on the + sign in the Run and Debug area of VSCode and adding MyPackage?

Should I load Revise.jl while I am debugging with the Julia Interpreter? What would be the pros and cons?

---

<div class="post-metadata">

**Author:** ![Soldalma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/soldalma/32/29388_2.png) [@Soldalma](https://discourse.julialang.org/u/Soldalma)\
**Post date:** [June 5, 2023, 3:45pm UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/40 "2023-06-05T15:45:43Z")

</div>

I am assuming

```julia
...
@enter myfunc() # or @enter MyPackage.myfunc()
...

```

would replace the call

```julia
...
myfunc()
...

```

within my code. Is this correct?

---

<div class="post-metadata">

**Author:** ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)\
**Post date:** [June 5, 2023, 4:05pm UTC](https://discourse.julialang.org/t/debugging-extremely-slow/53801/41 "2023-06-05T16:05:39Z")

</div>

I just run the `@enter` line in the REPL directly, without putting it in the code.

[Previous page](https://discourse.julialang.org/t/debugging-extremely-slow/53801.md?page=1)

[Next page](https://discourse.julialang.org/t/debugging-extremely-slow/53801.md?page=3)
