Skip to content

Commit 8a2374a

Browse files
IanButterworthKristofferC
authored andcommitted
Add compilation & recompilation time to time_imports macro (#45064)
(cherry picked from commit 9320fba)
1 parent 54293ec commit 8a2374a

File tree

4 files changed

+44
-15
lines changed

4 files changed

+44
-15
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ New library features
110110
* TCP socket objects now expose `closewrite` functionality and support half-open mode usage ([#40783]).
111111
* `extrema` now accepts an `init` keyword argument ([#36265], [#43604]).
112112
* `Iterators.countfrom` now accepts any type that defines `+` ([#37747]).
113+
* `@time_imports` now shows any compilation and recompilation time percentages per import ([#45064]).
113114

114115
Standard library changes
115116
------------------------

base/loading.jl

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,13 @@ const TIMING_IMPORTS = Threads.Atomic{Int}(0)
895895
# returns `false` if the module isn't known to be precompilable
896896
# returns the set of modules restored if the cache load succeeded
897897
@constprop :none function _require_search_from_serialized(pkg::PkgId, sourcepath::String, depth::Int = 0)
898-
t_before = time_ns()
898+
timing_imports = TIMING_IMPORTS[] > 0
899+
try
900+
if timing_imports
901+
t_before = time_ns()
902+
cumulative_compile_timing(true)
903+
t_comp_before = cumulative_compile_time_ns()
904+
end
899905
paths = find_all_in_cache_path(pkg)
900906
for path_to_try in paths::Vector{String}
901907
staledeps = stale_cachefile(sourcepath, path_to_try)
@@ -927,17 +933,29 @@ const TIMING_IMPORTS = Threads.Atomic{Int}(0)
927933
if isa(restored, Exception)
928934
@debug "Deserialization checks failed while attempting to load cache from $path_to_try" exception=restored
929935
else
930-
if TIMING_IMPORTS[] > 0
936+
if timing_imports
931937
elapsed = round((time_ns() - t_before) / 1e6, digits = 1)
938+
comp_time, recomp_time = cumulative_compile_time_ns() .- t_comp_before
932939
tree_prefix = depth == 0 ? "" : " "^(depth-1)*""
933940
print(lpad(elapsed, 9), " ms ")
934941
printstyled(tree_prefix, color = :light_black)
935-
println(pkg.name)
942+
print(pkg.name)
943+
if comp_time > 0
944+
printstyled(" ", Ryu.writefixed(Float64(100 * comp_time / (elapsed * 1e6)), 2), "% compilation time", color = Base.info_color())
945+
end
946+
if recomp_time > 0
947+
perc = Float64(100 * recomp_time / comp_time)
948+
printstyled(" (", perc < 1 ? "<1" : Ryu.writefixed(perc, 0), "% recompilation)", color = Base.warn_color())
949+
end
950+
println()
936951
end
937952
return restored
938953
end
939954
end
940955
return !isempty(paths)
956+
finally
957+
timing_imports && cumulative_compile_timing(false)
958+
end
941959
end
942960

943961
# to synchronize multiple tasks trying to import/using something

stdlib/InteractiveUtils/src/macros.jl

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -354,24 +354,34 @@ See also: [`code_native`](@ref), [`@code_llvm`](@ref), [`@code_typed`](@ref) and
354354
@time_imports
355355
356356
A macro to execute an expression and produce a report of any time spent importing packages and their
357-
dependencies.
357+
dependencies. Any compilation time will be reported as a percentage, and how much of which was recompilation, if any.
358358
359359
If a package's dependencies have already been imported either globally or by another dependency they will
360360
not appear under that package and the package will accurately report a faster load time than if it were to
361361
be loaded in isolation.
362362
363+
!!! compat "Julia 1.9"
364+
Reporting of any compilation and recompilation time was added in Julia 1.9
365+
363366
```julia-repl
364367
julia> @time_imports using CSV
365-
3.5 ms ┌ IteratorInterfaceExtensions
366-
27.4 ms ┌ TableTraits
367-
614.0 ms ┌ SentinelArrays
368-
138.6 ms ┌ Parsers
369-
2.7 ms ┌ DataValueInterfaces
370-
3.4 ms ┌ DataAPI
371-
59.0 ms ┌ WeakRefStrings
372-
35.4 ms ┌ Tables
373-
49.5 ms ┌ PooledArrays
374-
972.1 ms CSV
368+
0.4 ms ┌ IteratorInterfaceExtensions
369+
11.1 ms ┌ TableTraits 84.88% compilation time
370+
145.4 ms ┌ SentinelArrays 66.73% compilation time
371+
42.3 ms ┌ Parsers 19.66% compilation time
372+
4.1 ms ┌ Compat
373+
8.2 ms ┌ OrderedCollections
374+
1.4 ms ┌ Zlib_jll
375+
2.3 ms ┌ TranscodingStreams
376+
6.1 ms ┌ CodecZlib
377+
0.3 ms ┌ DataValueInterfaces
378+
15.2 ms ┌ FilePathsBase 30.06% compilation time
379+
9.3 ms ┌ InlineStrings
380+
1.5 ms ┌ DataAPI
381+
31.4 ms ┌ WeakRefStrings
382+
14.8 ms ┌ Tables
383+
24.2 ms ┌ PooledArrays
384+
2002.4 ms CSV 83.49% compilation time
375385
```
376386
377387
!!! note

stdlib/InteractiveUtils/test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ end
641641
buf = read(fname)
642642
rm(fname)
643643

644-
@test occursin("ms Foo3242\n", String(buf))
644+
@test occursin("ms Foo3242", String(buf))
645645

646646
finally
647647
filter!(()(dir), LOAD_PATH)

0 commit comments

Comments
 (0)