I want to record statistics about calls of some functions – the number of calls, runtime, etc. – without modifying the function code (or the code in the function parent module).
using TraceIt
@trace Base.sum; @trace Base.log
reduce(log, map(sum, [[1, 2, 3], [4, 5], [6]]))
printtrace() # mostly compilation time
Func. ╲ Stat. │ called mem, b gctime, s time, s time, %
──────────────┼──────────────────────────────────────────────
sum │ 3 12272 0.0 0.0102889 54.94 %
log │ 2 138281 0.0 0.0084373 45.06 %
──────────────┼──────────────────────────────────────────────
Σ │ 5 150553 0.0 0.0187262 100.0 %
Internally, @trace Foo.foo does
primary_world = Base.get_world_counter()
@eval Foo function foo(x)
#= record statistics globally =#
@info "foo is now traced!"
return Base.invoke_in_world($primary_world, foo, x)
end
As I understand, this is not ideal. Tracing the functions that are nested will become complicated, and Base.invoke_in_world itself has overhead. (also, I realize that @eval inside of a macro is a bad idea; please bear with me :^D)
Is there a way to implement such tracing that could be better ?
I have created a thing called “logging profiler” as a toy example when teaching generated functions. It is implemented here GitHub - pevnak/LoggingProfiler.jl: A profiler that logs beggning and and of each function, but I have touch it for a while and not sure about the state. If it is what you are looking for, I will be happy to help you to make this work. What stopped me to finish the project was that I did not know, how to deal with multi-threadding properly.