How to understand Traceur's output?

I am not sure, that I understand correctly the performance tips regards type declarations and containers with abstract types, so I tested my code with Traceur.
But I don’t really understand the output, could you please help me with it?
I have this code in mwe.jl:

using Dates

abstract type AbstractWorkoutType end

struct RunningWorkout <: AbstractWorkoutType
	distance::Float64
end

struct GymWorkout <: AbstractWorkoutType
	type::String
end

struct Workout{T<:AbstractWorkoutType}
	date::DateTime
	workout::T
	effort::Union{Int64, Nothing}
end

function traceme()
	dt1 = DateTime(2019,1,1)
	dt2 = DateTime(2019,1,2)

	r = RunningWorkout(1.5)
	g = GymWorkout("push ups")

	w1 = Workout(dt1, r, nothing)
	w2 = Workout(dt2, g, 5)

	return [w1, w2]
end

If I ran @trace, I get the following:

julia> include("mwe.jl")
traceme (generic function with 1 method)

julia> traceme()
2-element Array{Workout,1}:
 Workout{RunningWorkout}(2019-01-01T00:00:00, RunningWorkout(1.5), nothing)
 Workout{GymWorkout}(2019-01-02T00:00:00, GymWorkout("push ups"), 5)

julia> using Traceur

julia> @trace traceme()
┌ Warning: err is assigned as Union{Nothing, ArgumentError}
└ @ C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.1\Dates\src\types.jl:182
┌ Warning: unsafe_pointer_to_objref returns Any
└ @ pointer.jl:128
┌ Warning: getindex returns Any
└ @ essentials.jl:549
┌ Warning: getindex returns Any
└ @ array.jl:729
┌ Warning: aprimary is assigned as Type{Workout}
└ @ promotion.jl:95
┌ Warning: aprimary is assigned as Type{Workout{T<:AbstractWorkoutType}}
└ @ promotion.jl:108
┌ Warning: aprimary is assigned as Any
└ @ promotion.jl:112
┌ Warning: dynamic dispatch to (Base.UnionAll)(φ (%97 => %93, %119 => %114), φ (%97 => %82, %119 => %101))
└ @ promotion.jl:112
┌ Warning: typejoin returns Any
└ @ promotion.jl:16
┌ Warning: getindex returns Union{Workout{GymWorkout}, Workout{RunningWorkout}}
└ @ tuple.jl:24
┌ Warning: x is assigned as Union{Workout{GymWorkout}, Workout{RunningWorkout}}
└ @ abstractarray.jl:668
┌ Warning: y is assigned as Union{Nothing, Tuple{Int64,Int64}}
└ @ abstractarray.jl:667
┌ Warning: y is assigned as Union{Nothing, Tuple{Int64,Int64}}
└ @ abstractarray.jl:672
2-element Array{Workout,1}:
 Workout{RunningWorkout}(2019-01-01T00:00:00, RunningWorkout(1.5), nothing)
 Workout{GymWorkout}(2019-01-02T00:00:00, GymWorkout("push ups"), 5)

I don’t understand where these warnings come from, and whether I can ignore them.
Later I wan to operate on arrays of Workout, and while this current example is not performance critical, I have similar types at another project where speed does matter, so I would like to do it right.

Thank you for your help in advance!

1 Like

Same for me. At least for newcomers it’s hard to understand what and where the issue is. It’d be so cool if it could point to the offending line in the code, stacktrace style, and to the relevant performance tips section… not a complaint, Traceur is great and I’m sure that it’ll all become more obvious as we learn from our mistakes. I just wish it shoved my nose into the mess and shouted out what I did wrong.

EDIT:
Looking at the announcement, the output shown there does look a lot like what I was wishing for, whereas mine is like cserteGT3’s. Should @trace be run in the REPL, have other things changed (e.g. some people point out that @code_warntype output used to be more easily legible) or am I making a mistake?

Ok, so the printing isn’t ideal, but whenever you only see a filename that’s a function in Base and therefore something you’re most likely not interested in.

Take a look at the docs for @trace:

help?> @trace
  @trace(functioncall(args...), maxdepth=2, modules=[])

  Analyse functioncall(args...) for common performance problems and print them to the
  terminal.

  Optional arguments:

    •    maxdepth constrols how far Traceur recurses through the call stack.

    •    If modules is nonempty, only warnings for methods defined in one of the modules
        specified will be printed.

In your case you’re probably only interested in issues in your code, so try e.g.

julia> @trace(traceme(), modules=[Main])
2-element Array{Workout,1}:
 Workout{RunningWorkout}(DateTime(2019, 1, 1, 0, 0, 0), RunningWorkout(1.5), nothing)
 Workout{GymWorkout}(DateTime(2019, 1, 2, 0, 0, 0), GymWorkout("push ups"), 5)      

which doesn’t find any problems.

If you have any ideas for improving the REPL output then feel free to open an issue or PR at the Traceur repo.

You might also be interested in the Juno interface:

3 Likes

Thank you, I had the assumption that these warnings mean that I’m probably OK.
Sorry for missing the docs, I tend to forget that it’s close-at-hand.

Thanks for the advice, very helpful! I wasn’t aware of the Juno.@trace command, that’s great. It may be worth highlighting this option in the docs. Similarly, a suggestion that users might wish to start the analysis by adding kwarg modules=[MyModule] could also be helpful for new users.