# Retain computation results with @btime

**URL:** <https://discourse.julialang.org/t/retain-computation-results-with-btime/62644>\
**Category:** New to Julia\
**Created:** [June 9, 2021, 8:50pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644 "2021-06-09T20:50:47Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![jinml](https://avatars.discourse-cdn.com/v4/letter/j/91b2a8/32.png) [@jinml](https://discourse.julialang.org/u/jinml)\
**Post date:** [June 9, 2021, 8:50pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/1 "2021-06-09T20:50:47Z")

</div>

I’m trying to time a function and keep its return value:  
`b = @btime y = foo(x)`  
but at the end y is not returned. How can get @btime to also return my result?

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [June 9, 2021, 8:54pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/2 "2021-06-09T20:54:15Z")

</div>

Use `@belapsed` instead.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [June 9, 2021, 9:35pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/3 "2021-06-09T21:35:30Z")

</div>

> [@Save @btime output](https://discourse.julialang.org/t/save-btime-output/53595/6):
>
> This is asked every other week, so probably we should have it directly in BenchmarkTools: julia\> @eval BenchmarkTools macro btimed(args...) \_, params = prunekwargs(args...) bench, trial, result = gensym(), gensym(), gensym() trialmin, trialallocs = gensym(), gensym() tune\_phase = hasevals(params) ? :() : :($BenchmarkTools.tune!($bench)) return esc(quote local $bench = $BenchmarkTools.@benchmarkable $(args...) $…

---

<div class="post-metadata">

**Author:** ![ctkelley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ctkelley/32/10684_2.png) [@ctkelley](https://discourse.julialang.org/u/ctkelley)\
**Post date:** [June 9, 2021, 10:19pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/4 "2021-06-09T22:19:47Z")

</div>

I’m not clear on why you need this. I use

bar = foo(spam);

when I want results and

@btime foo($spam);

when I want to see how fast my function is. These are different missions for me.

---

<div class="post-metadata">

**Author:** ![jinml](https://avatars.discourse-cdn.com/v4/letter/j/91b2a8/32.png) [@jinml](https://discourse.julialang.org/u/jinml)\
**Post date:** [June 9, 2021, 10:46pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/5 "2021-06-09T22:46:48Z")

</div>

@belapsed did not seem to work, @elapsed did. Moreover, @btime provides more info than just time and is supposed to be more accurate ?

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [June 10, 2021, 6:16am UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/6 "2021-06-10T06:16:41Z")

</div>

What did not work? Can you show a reproducible example and tell us your expected behaviour?

---

<div class="post-metadata">

**Author:** ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)\
**Post date:** [June 10, 2021, 6:43am UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/7 "2021-06-10T06:43:00Z")

</div>

It sounds like you just want

```julia
y = @btime foo(x)

```

However, I don’t see how this is useful. If this is part of a computation where you use `y` later, you probably don’t want to run `foo(x)` multiple times (which is what `@btime` does).

---

<div class="post-metadata">

**Author:** ![jinml](https://avatars.discourse-cdn.com/v4/letter/j/91b2a8/32.png) [@jinml](https://discourse.julialang.org/u/jinml)\
**Post date:** [June 10, 2021, 1:22pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/8 "2021-06-10T13:22:17Z")

</div>

This is what I meant. @belapsed cannot return the computation result as I needed.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/5/c58af2cd4034de7817a14c044faa960cd0b24af8.png)

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [June 10, 2021, 4:51pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/9 "2021-06-10T16:51:37Z")

</div>

What doesn’t work in the link I shared above?

```julia
julia> @eval BenchmarkTools macro btimed(args...)
           _, params = prunekwargs(args...)
           bench, trial, result = gensym(), gensym(), gensym()
           trialmin, trialallocs = gensym(), gensym()
           tune_phase = hasevals(params) ? :() : :($BenchmarkTools.tune!($bench))
           return esc(quote
               local $bench = $BenchmarkTools.@benchmarkable $(args...)
               $BenchmarkTools.warmup($bench)
               $tune_phase
               local $trial, $result = $BenchmarkTools.run_result($bench)
               local $trialmin = $BenchmarkTools.minimum($trial)
               $result, $BenchmarkTools.time($trialmin)
           end)
       end
@btimed (macro with 1 method)

julia> b, y = BenchmarkTools.@btimed sin(12.3)
(-0.26323179136580094, 1.371)

julia> b
-0.26323179136580094

julia> y
1.371

```

Isn’t this what you want?

---

<div class="post-metadata">

**Author:** ![jinml](https://avatars.discourse-cdn.com/v4/letter/j/91b2a8/32.png) [@jinml](https://discourse.julialang.org/u/jinml)\
**Post date:** [June 10, 2021, 8:12pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/10 "2021-06-10T20:12:03Z")

</div>

Yes. I replied to the wrong post

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [January 25, 2023, 8:25am UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/11 "2023-01-25T08:25:54Z")

</div>

it would be great to have a way to do both though. Otherwise it’s just a waste of compute resources. [BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl) already calculates the result, why not also return it if needed ?

Tha solution from @giordano is appropriate for cases where the result is deterministic, and it would be nice to see it in BenchmarkTools.jl. (plus the variation to get the whole `@benchmark` metrics).  
However, I am mostly preoccupied with cases where there is some stochasticity in the results, i.e. they’re not always the same. In these cases, it would be great to also return a vector of all calculated results (of the same length as the samples).

The [docs in BenchmarkTools.jl](https://juliaci.github.io/BenchmarkTools.jl/dev/manual/#Miscellaneous-tips-and-info) specify the user should strive for reproducibility by e.g. using the same seed. Sometimes the nature of benchmarking itself is explorative and a variety of the results it’s expected. At that point, it would be nice to have the computed result accompanying the performance benchmark.

I can see that the motivation might be a bit shady, because now it’s not only about benchmarking performance of a function but also the content and functionality, but overall I think it would make a worthwhile addition.

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [December 19, 2024, 9:28am UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/12 "2024-12-19T09:28:46Z")

</div>

May I ask why is this macro not shipped inside BenchmarkTools.jl?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [December 19, 2024, 9:34am UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/13 "2024-12-19T09:34:41Z")

</div>

I guess because no one bothered to submit a PR?

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [December 19, 2024, 9:41am UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/14 "2024-12-19T09:41:03Z")

</div>

If that’s the case, shall I do that?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [December 19, 2024, 9:51am UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/15 "2024-12-19T09:51:50Z")

</div>

I guess you can if you’re motivated, yes.

---

<div class="post-metadata">

**Author:** ![willow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/willow/32/208918_2.png) [@willow](https://discourse.julialang.org/u/willow)\
**Post date:** [December 22, 2024, 5:21pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/16 "2024-12-22T17:21:18Z")

</div>

I’m a little confused. The `@btime` macro _does_ return the result of the expression being timed. It just doesn’t set global variables. For example:

```julia
               _
   _ _ _(_)_ | Documentation: https://docs.julialang.org
  (_) | (_) (_) |
   _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` | |
  | | |_| | | | (_| | | Version 1.11.1 (2024-10-16)
 _/ |\ __'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |

(@v1.11) pkg> st BenchmarkTools
Status `~/.julia/environments/v1.11/Project.toml`
  [6e4b80f9] BenchmarkTools v1.5.0

julia> using BenchmarkTools

julia> foo(x) = x + 1
foo (generic function with 1 method)

julia> x = 3
3

julia> b = @btime y = foo(x)
  7.750 ns (0 allocations: 0 bytes)
4

julia> b
4

julia> y
ERROR: UndefVarError: `y` not defined in `Main`
Suggestion: check for spelling errors or missing imports.

```

The result of the computation appears to be returned, and this has been the behavior for at least the past 7 years: [Blaming BenchmarkTools.jl/src/execution.jl at b789f01a9069950f7eb49991e290895472896294 · JuliaCI/BenchmarkTools.jl · GitHub](https://github.com/JuliaCI/BenchmarkTools.jl/blame/b789f01a9069950f7eb49991e290895472896294/src/execution.jl#L592)

This directly mimics the behavior of `@time`.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [December 22, 2024, 10:05pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/17 "2024-12-22T22:05:23Z")

</div>

I presume OP wanted to keep both the timing _and_ the result. That’s what [`Base.@timed`](https://docs.julialang.org/en/v1/base/base/#Base.@timed) does, and the above proposed `@btimed` does as well to mimic `Base.@timed`.

---

<div class="post-metadata">

**Author:** ![willow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/willow/32/208918_2.png) [@willow](https://discourse.julialang.org/u/willow)\
**Post date:** [December 23, 2024, 2:23pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/18 "2024-12-23T14:23:53Z")

</div>

Sounds good! The PR is merged: [Add `@btimed` and `@ballocations` macros by singularitti · Pull Request #383 · JuliaCI/BenchmarkTools.jl · GitHub](https://github.com/JuliaCI/BenchmarkTools.jl/pull/383)

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [December 23, 2024, 8:31pm UTC](https://discourse.julialang.org/t/retain-computation-results-with-btime/62644/19 "2024-12-23T20:31:30Z")

</div>

Thank you for your help @giordano @willow!
