try/finally blocks are not the answer for performance critical code
Yeah, I did actually think about using try/finally here but it was a bit too costly to build into @no_escape, though it is actually cheaper than one might think, e.g.
julia> function foo1(buf=default_buffer())
@no_escape buf begin
z = @alloc(Int, 10)
z .= 1
sum(z)
end
end;
julia> function foo2(buf=default_buffer())
b = default_buffer()
cp = Bumper.checkpoint_save(b)
try
foo1(buf)
finally
Bumper.checkpoint_restore!(cp)
end
end;
and then
julia> @btime foo1();
12.717 ns (0 allocations: 0 bytes)
julia> @btime foo2();
34.566 ns (0 allocations: 0 bytes)
julia> @btime foo1($(default_buffer()));
5.610 ns (0 allocations: 0 bytes)
julia> @btime foo2($(default_buffer()));
26.099 ns (0 allocations: 0 bytes)
so if you never actually hit the finally branch it’s not that expensive to have around so long as you’re not using it in the tightest of tight loops.
I could also make a varitant of @no_escape that does the finally branch automatically, e.g. it could be called @no_escape_finally or something, would that help?
Good idea.