Skip to content

Commit 5ecf5fc

Browse files
Add optional description to @time and new @showtime macro (JuliaLang#42431)
1 parent 2def71f commit 5ecf5fc

File tree

5 files changed

+92
-3
lines changed

5 files changed

+92
-3
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ Language changes
2222
* Newly created Task objects (`@spawn`, `@async`, etc.) now adopt the world-age for methods from their parent
2323
Task upon creation, instead of using the global latest world at start. This is done to enable inference to
2424
eventually optimize these calls. Places that wish for the old behavior may use `Base.invokelatest`. ([#41449])
25+
* `@time` and `@timev` now take an optional description to allow annotating the source of time reports.
26+
i.e. `@time "Evaluating foo" foo()` ([#42431])
27+
* New `@showtime` macro to show both the line being evaluated and the `@time` report ([#42431])
2528

2629
Compiler/Runtime improvements
2730
-----------------------------

base/exports.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,7 @@ export
992992

993993
# profiling
994994
@time,
995+
@showtime,
995996
@timed,
996997
@timev,
997998
@elapsed,

base/timing.jl

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,25 +175,31 @@ macro __tryfinally(ex, fin)
175175
end
176176

177177
"""
178-
@time
178+
@time expr
179+
@time "description" expr
179180
180181
A macro to execute an expression, printing the time it took to execute, the number of
181182
allocations, and the total number of bytes its execution caused to be allocated, before
182183
returning the value of the expression. Any time spent garbage collecting (gc) or
183184
compiling is shown as a percentage.
184185
186+
Optionally provide a description string to print before the time report.
187+
185188
In some cases the system will look inside the `@time` expression and compile some of the
186189
called code before execution of the top-level expression begins. When that happens, some
187190
compilation time will not be counted. To include this time you can run `@time @eval ...`.
188191
189-
See also [`@timev`](@ref), [`@timed`](@ref), [`@elapsed`](@ref), and
192+
See also [`@showtime`](@ref), [`@timev`](@ref), [`@timed`](@ref), [`@elapsed`](@ref), and
190193
[`@allocated`](@ref).
191194
192195
!!! note
193196
For more serious benchmarking, consider the `@btime` macro from the BenchmarkTools.jl
194197
package which among other things evaluates the function multiple times in order to
195198
reduce noise.
196199
200+
!!! compat "Julia 1.8"
201+
The option to add a description was introduced in Julia 1.8.
202+
197203
```julia-repl
198204
julia> x = rand(10,10);
199205
@@ -209,9 +215,24 @@ julia> @time begin
209215
end
210216
0.301395 seconds (8 allocations: 336 bytes)
211217
2
218+
219+
julia> @time "A one second sleep" sleep(1)
220+
A one second sleep -> 1.005750 seconds (5 allocations: 144 bytes)
221+
222+
julia> for loop in 1:3
223+
@time loop sleep(1)
224+
end
225+
1 -> 1.006760 seconds (5 allocations: 144 bytes)
226+
2 -> 1.001263 seconds (5 allocations: 144 bytes)
227+
3 -> 1.003676 seconds (5 allocations: 144 bytes)
212228
```
213229
"""
214230
macro time(ex)
231+
quote
232+
@time nothing $(esc(ex))
233+
end
234+
end
235+
macro time(msg, ex)
215236
quote
216237
Experimental.@force_compile
217238
local stats = gc_num()
@@ -222,18 +243,46 @@ macro time(ex)
222243
compile_elapsedtime = cumulative_compile_time_ns_after() - compile_elapsedtime)
223244
)
224245
local diff = GC_Diff(gc_num(), stats)
246+
isnothing($(esc(msg))) || print($(esc(msg)), " ->")
225247
time_print(elapsedtime, diff.allocd, diff.total_time, gc_alloc_count(diff), compile_elapsedtime, true)
226248
val
227249
end
228250
end
229251

230252
"""
231-
@timev
253+
@showtime expr
254+
255+
Like `@time` but also prints the expression being evaluated for reference.
256+
257+
!!! compat "Julia 1.8"
258+
This macro was added in Julia 1.8.
259+
260+
See also [`@time`](@ref).
261+
262+
```julia-repl
263+
julia> @showtime sleep(1)
264+
sleep(1) -> 1.002164 seconds (4 allocations: 128 bytes)
265+
```
266+
"""
267+
macro showtime(ex)
268+
quote
269+
@time $(sprint(show_unquoted,ex)) $(esc(ex))
270+
end
271+
end
272+
273+
"""
274+
@timev expr
275+
@timev "description" expr
232276
233277
This is a verbose version of the `@time` macro. It first prints the same information as
234278
`@time`, then any non-zero memory allocation counters, and then returns the value of the
235279
expression.
236280
281+
Optionally provide a description string to print before the time report.
282+
283+
!!! compat "Julia 1.8"
284+
The option to add a description was introduced in Julia 1.8.
285+
237286
See also [`@time`](@ref), [`@timed`](@ref), [`@elapsed`](@ref), and
238287
[`@allocated`](@ref).
239288
@@ -259,6 +308,11 @@ pool allocs: 1
259308
```
260309
"""
261310
macro timev(ex)
311+
quote
312+
@timev nothing $(esc(ex))
313+
end
314+
end
315+
macro timev(msg, ex)
262316
quote
263317
Experimental.@force_compile
264318
local stats = gc_num()
@@ -269,6 +323,7 @@ macro timev(ex)
269323
compile_elapsedtime = cumulative_compile_time_ns_after() - compile_elapsedtime)
270324
)
271325
local diff = GC_Diff(gc_num(), stats)
326+
isnothing($(esc(msg))) || print($(esc(msg)), " ->")
272327
timev_print(elapsedtime, diff, compile_elapsedtime)
273328
val
274329
end

doc/src/base/base.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ Base.Libc.getpid
320320
Base.Libc.time()
321321
Base.time_ns
322322
Base.@time
323+
Base.@showtime
323324
Base.@timev
324325
Base.@timed
325326
Base.@elapsed

test/misc.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,35 @@ v11801, t11801 = @timed sin(1)
242242

243243
@test names(@__MODULE__, all = true) == names_before_timing
244244

245+
# Accepted @time argument formats
246+
@test @time true
247+
@test @time "message" true
248+
let msg = "message"
249+
@test @time msg true
250+
end
251+
let foo() = "message"
252+
@test @time foo() true
253+
end
254+
255+
# Accepted @timev argument formats
256+
@test @timev true
257+
@test @timev "message" true
258+
let msg = "message"
259+
@test @timev msg true
260+
end
261+
let foo() = "message"
262+
@test @timev foo() true
263+
end
264+
265+
# @showtime
266+
@test @showtime true
267+
let foo() = true
268+
@test @showtime foo()
269+
end
270+
let foo() = false
271+
@test (@showtime foo()) == false
272+
end
273+
245274
# PR #39133, ensure that @time evaluates in the same scope
246275
function time_macro_scope()
247276
try # try/throw/catch bypasses printing

0 commit comments

Comments
 (0)