Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add @allocations macro for getting number of allocations #47367

Merged
merged 4 commits into from
Nov 4, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,7 @@ export
@timev,
@elapsed,
@allocated,
@allocations,

# tasks
@sync,
Expand Down
43 changes: 35 additions & 8 deletions base/timing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ In some cases the system will look inside the `@time` expression and compile som
called code before execution of the top-level expression begins. When that happens, some
compilation time will not be counted. To include this time you can run `@time @eval ...`.

See also [`@showtime`](@ref), [`@timev`](@ref), [`@timed`](@ref), [`@elapsed`](@ref), and
[`@allocated`](@ref).
See also [`@showtime`](@ref), [`@timev`](@ref), [`@timed`](@ref), [`@elapsed`](@ref),
[`@allocated`](@ref), and [`@allocations`](@ref).

!!! note
For more serious benchmarking, consider the `@btime` macro from the BenchmarkTools.jl
Expand Down Expand Up @@ -318,8 +318,8 @@ Optionally provide a description string to print before the time report.
!!! compat "Julia 1.8"
The option to add a description was introduced in Julia 1.8.

See also [`@time`](@ref), [`@timed`](@ref), [`@elapsed`](@ref), and
[`@allocated`](@ref).
See also [`@time`](@ref), [`@timed`](@ref), [`@elapsed`](@ref),
[`@allocated`](@ref), and [`@allocations`](@ref).

```julia-repl
julia> x = rand(10,10);
Expand Down Expand Up @@ -379,7 +379,7 @@ called code before execution of the top-level expression begins. When that happe
compilation time will not be counted. To include this time you can run `@elapsed @eval ...`.

See also [`@time`](@ref), [`@timev`](@ref), [`@timed`](@ref),
and [`@allocated`](@ref).
[`@allocated`](@ref), and [`@allocations`](@ref).

```julia-repl
julia> @elapsed sleep(0.3)
Expand Down Expand Up @@ -410,7 +410,7 @@ end
A macro to evaluate an expression, discarding the resulting value, instead returning the
total number of bytes allocated during evaluation of the expression.

See also [`@time`](@ref), [`@timev`](@ref), [`@timed`](@ref),
See also [`@allocations`](@ref), [`@time`](@ref), [`@timev`](@ref), [`@timed`](@ref),
and [`@elapsed`](@ref).

```julia-repl
Expand All @@ -430,6 +430,33 @@ macro allocated(ex)
end
end

"""
@allocations

A macro to evaluate an expression, discard the resulting value, and instead return the
total number of allocations during evaluation of the expression.

See also [`@allocated`](@ref), [`@time`](@ref), [`@timev`](@ref), [`@timed`](@ref),
and [`@elapsed`](@ref).

```julia-repl
julia> @allocations rand(10^6)
2
```

!!! compat "Julia 1.9"
This macro was added in Julia 1.9.
nickrobinson251 marked this conversation as resolved.
Show resolved Hide resolved
"""
macro allocations(ex)
quote
Experimental.@force_compile
nickrobinson251 marked this conversation as resolved.
Show resolved Hide resolved
local stats = Base.gc_num()
$(esc(ex))
local diff = Base.GC_Diff(Base.gc_num(), stats)
Base.gc_alloc_count(diff)
end
end

"""
@timed

Expand All @@ -441,8 +468,8 @@ In some cases the system will look inside the `@timed` expression and compile so
called code before execution of the top-level expression begins. When that happens, some
compilation time will not be counted. To include this time you can run `@timed @eval ...`.

See also [`@time`](@ref), [`@timev`](@ref), [`@elapsed`](@ref), and
[`@allocated`](@ref).
See also [`@time`](@ref), [`@timev`](@ref), [`@elapsed`](@ref),
[`@allocated`](@ref), and [`@allocations`](@ref).

```julia-repl
julia> stats = @timed rand(10^6);
Expand Down
1 change: 1 addition & 0 deletions doc/src/base/base.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ Base.@timev
Base.@timed
Base.@elapsed
Base.@allocated
Base.@allocations
Base.EnvDict
Base.ENV
Base.Sys.STDLIB
Expand Down
4 changes: 2 additions & 2 deletions doc/src/manual/profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,8 @@ provides several tools measure this:

### `@time`

The total amount of allocation can be measured with [`@time`](@ref) and [`@allocated`](@ref), and
specific lines triggering allocation can often be inferred from profiling via the cost of garbage
The total amount of allocation can be measured with [`@time`](@ref), [`@allocated`](@ref) and [`@allocations`](@ref),
and specific lines triggering allocation can often be inferred from profiling via the cost of garbage
collection that these lines incur. However, sometimes it is more efficient to directly measure
the amount of memory allocated by each line of code.

Expand Down
4 changes: 4 additions & 0 deletions test/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1234,4 +1234,8 @@ end

@testset "Base/timing.jl" begin
@test Base.jit_total_bytes() >= 0

# sanity check `@allocations` returns what we expect in some very simple cases
@test (@allocations "a") == 0
@test (@allocations "a" * "b") == 1
end