Debugging extremely slow

I’m currently trying to make the switch from Matlab to Julia 1.5.3. I am currently working with Atom/Juno (Atom 1.54.0, uber-juno 0.3.0) because of it’s similarity to the the Matlab editor. While I like many things in Julia, I’m having a really hard time debugging my code. Coming from Matlab, I am used to set breakpoints to see the definition of variables inside loops, functions etc. quickly.

In Juno, evaluating steps in the debugger takes AGES (I am speaking of minutes!) unless the function is very simple. I’ve been searching for solutions for a quite long time now and my current understanding is that this is to be expected(?) I would be grateful for a brief reply from an expert. Are there any good alternatives to Atom/Juno?

Thanks!

4 Likes

Julia’s interpreted mode is known to be pretty slow - speeding it up is a work in progress. The best way to quickly drop into a function’s scope is Infiltrator.jl, or you can use Exfiltrator.jl to send variables in deeply-nested scopes back to the global scope. Both should be just as fast as any other JIT-compiled method.

3 Likes

Thanks a lot! I’ve tried “Infiltrator.jl” and it seems to be a valuable tool.

Believe it or not, I suspect that one of Matlab’s advantages here is that all the performance-sensitive stuff is written in C and their debugger doesn’t step into it. So their debugger only lets you look at surface level logic, but the flip side is that it doesn’t really hurt performance. Conversely, the Julia debugger goes down to every single operation, and that just kills performance.

As a first cut you can try

julia> using JuliaInterpreter

julia> push!(JuliaInterpreter.compiled_modules, Base)
Set{Module} with 2 elements:
  Base.Threads
  Base

and see if it helps. (That will cause it to skip debugging for every method defined in Base.) Or, if you really want to exclude everything in Base, do

julia> using MethodAnalysis

julia> visit(Base) do item
           isa(item, Module) && push!(JuliaInterpreter.compiled_modules, item)
           true
       end

which will block every submodule of Base too. You might need to add some stdlibs too.

32 Likes

It might be worth switching to VSCode since development on Atom is being phased out. Although switching probably won’t solve your debugging issues, VSCode seems to be more responsive overall. Both IDEs have similar features and setups.

Hi Tim.

Thanks for this great advice.
Your first suggestion shortened the degugger to reach my breakpoint from “forever” to about 40 seconds.
Your second suggestion shortened it further to a second or so. Now it really feels like Matlab: I can step quickly through all the lines and see how variables develop.

I would really appreciate if there would be a simple button “Debugger for dummies” :wink: or something similar in a Julia editor that would allow for this kind of “superficial” inspection.

I’ve noticed that the Juno debugger seems to deliver many more details on the code than Matlab’s. But frankly speaking, I am not an IT specialist and don’t understand code at this level anyway.

9 Likes

Perhaps these two options could be added to Juno or vscode to improve the user experience? Would that be possible?

11 Likes

In my opinion, there should be 4 levels of exclusion. The default should be to compile everything except deved packages and code outside packages. The next should be to compile everything in base and stdlib. The third should be to compile only base, and the 4th should be to compile nothing.

The reason to default to compiling everything is that new users mostly won’t be trying to debug external packages and are the least likely to know how to use startup.jl to change the behavior.

11 Likes

The biggest problem with that approach is that it breaks when higher order functions are used:

julia> f(x) = 2x
f (generic function with 1 method)

julia> breakpoint(f)
f

julia> outer(arr) = map(f, arr)
outer (generic function with 1 method)

julia> @run outer([1,2,3]) # this should break when `f` is called, but doesn't
3-element Array{Int64,1}:
 2
 4
 6
9 Likes

To resolve this, I propose that instead we should have: compile everything in Base except a predefined list of higher order functions.
It’s not perfect, but i think it would be relatively easy and get as a lot of the way there.
I have been told that this is feasible.

8 Likes

Ha, I totally forgot we talked about that idea. Will add a “compile all in module except for” functionality to UI for setting compiled funcs/mods by pfitzseb · Pull Request #1888 · julia-vscode/julia-vscode · GitHub.

7 Likes

I have a semi-automatically generated whitelist here and would be happy to add missing higher order functions in Base (or in stdlibs, actually) to that.

The list is called debuggerDefaultCompiled, is it a list of function that will or will not be compiled by default?

Yes :slight_smile: (depends on whether a function is prefixed with a - or not).

Ah, thanks for clarifying :slight_smile: I was thinking about list comprehensions

julia> Meta.@lower [a for a in 1:2]
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─ %1 = 1:2
│   %2 = Base.Generator(Base.identity, %1)
│   %3 = Base.collect(%2)
└──      return %3
))))

is it Generator that needs to be added?
EDIT: Oxinabox already pointed that out :+1:

I’m sorry for reviving an old thread, but I am in the same situation as OP (new to Julia from Matlab) and struggling to debug my code. I am running Julia v1.7 in VS Code. I just implemented the 2 suggestions by tim.holy, but the debugger is still too slow to be useful. Are there any other suggestions of things I could try? I will explore Infiltrator as a next step, but was hoping for a debugger that looks and feels like the one in Matlab…

4 Likes

You’re not alone. I’m a long time Matlab user but would love to give Julia a go, it has lots of promise and the open source community appeals to me.
I was worried about learning a new syntax but that is proving not too difficult. The insane debug times are putting me off though; its not just a little frustrating it’s nearly unworkeable for my workflow anyway. Also in VSCode.
I’m sure most users would be concerened mainly about debugging their own code at hand rather than absolutely everything. So I do like the previously mentioned ideas of that being default behaviour.

2 Likes

Debugging in vscode should work fine if configured correctly. Have a look at the end of this discussion to understand which settings are needed: https://github.com/julia-vscode/julia-vscode/issues/2465

1 Like

Thank you Uwe, I will take a look at your link!

One year has passed since the last activity from this topic. But this debugging problem is not resolved yet.
For test purposes a small piece of code with GLMakie plotting was created. First start of the app takes about 30 sec (with sysimage) and it could be tolerable somehow. But each time a debugger takes about 30-40 sec to start and it’s terribly slow. Code development becomes extremely slow and unpleasant.
I followed all recommendations in this topic and similar topics regarding GLMakie but with no significant positive effect.
The configuration is Julia 1.9.0-rc2 or 1.8.5, VScode with julia plugin v1.45.1, Win10 and all packages are uptodate.

Could you please advise me on the next tries?