Hey there! Maybe anybody can help me? I don’t understand how variables work in @belapsed.
My code:
function test_queue_deque(n)
@belapsed begin
for i in 1:n
popfirst!(dq)
end
end setup = begin
dq = Deque{Int}()
for _ in 1:n
push!(dq, 1)
end
end
end
ERROR: LoadError: UndefVarError: `j` not defined in `Main`
Suggestion: check for spelling errors or missing imports.
If I try to replace j with underscore, the code still doesn’t work. I get: ERROR: LoadError: syntax: all-underscore identifiers are write-only and their values cannot be used in expressions around
Put code between triple backticks like this so things properly format:
```
code
```
You can see those backticks because I used \ to escape them instead of specifying Markdown formatting.
As for your provided code, there’s no visible j variable anywhere so it wouldn’t throw the associated error. You likely provided the underscore edit instead but it’s not clear where the j would have been; if the underscore is replaced with j, the error would actually be about n.
There are a couple issues going on here. First, BenchmarkTools macros are designed to run their code in the global scope, so to put your argument n into the code, you have to interpolate them $n. Chairmarks.jl is an independent alternative that runs code in the macro call scope, if you prefer not to deal with global scope motion and are willing to take a chance on a newer less-known package. Second, BenchmarkTools transformed the code in some way that j or _ end up on the right hand side of a globally scoped assignment at some point, which isn’t what we want and isn’t allowed in the latter case. Refactor the setup code in a simpler function call as designed; loop variables are a genuine limitation of the setup expression that the benchmark expression doesn’t have.
julia> @btime sin(x) setup=(x=0; for i in 1:5 x+=i end) # simpler example
ERROR: UndefVarError: `i` not defined in `Main`
...
julia> foo() = (x=0; for i in 1:5 x+=i end; x); @btime sin(x) setup=(x=foo())
18.437 ns (0 allocations: 0 bytes)
0.6502878401571168
using DataStructures
function test_queue_deque(n)
@benchmark begin
for i = 1:$n
popfirst!(dq)
end
end setup = begin
dq = Deque{Int}()
push_all!(dq, $n)
end evals = 1
end
function push_all!(dq, n)
for _ = 1:n
push!(dq, 1)
end
end
test_queue_deque(3)
or
using DataStructures
function test_queue_deque(n)
@benchmark begin
for i = 1:$n
popfirst!(dq)
end
end setup = begin
dq = Deque{Int}()
j = 0
while (j += 1; j <= $n)
push!(dq, 1)
end
end evals = 1
end
test_queue_deque(3)
Key points are as follows:
Specify your dependencies when providing MREs.
All content within the entire begin code block is “wrapped” by the macro. To use the value of variable n, you must insert n using $.
@benchmark executes your begin…end block multiple times within a single sample, sharing the same dq.
Your code completely pops the dq in each execution, leading to an empty dq in later runs of the same sample and causing errors. I added evals = 1 at the end.