# Spinner/progress meter for slow functions

**URL:** https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385
**Category:** General Usage
**Tags:** question, time
**Created:** [February 19, 2024, 1:18am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385 "2024-02-19T01:18:11Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![math\_opt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/math_opt/32/25317_2.png) [@math\_opt](https://discourse.julialang.org/u/math_opt)
#### Post date: [February 19, 2024, 1:18am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/1 "2024-02-19T01:18:11Z")

</div>

I am aware of the package [ProgressMeter.jl](https://github.com/timholy/ProgressMeter.jl) which works for function which process things in loops. I am looking for something that works on functions that doesn’t necessarily have loop but just takes time to complete some complex calculation. Also, because there is no loop per se, so I am not expecting to display a progress meter, but simply a spinner would work just fine till the function is done executing.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [February 19, 2024, 1:33am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/2 "2024-02-19T01:33:04Z")

</div>

> [@math\_opt](#):
>
> Also, because there is no loop per se, so I am not expecting to display a progress meter, but simply a spinner would work just fine till the function is done executing.

See the ProgressMeter manual section on [tasks with an unknown number of steps](https://github.com/timholy/ProgressMeter.jl?tab=readme-ov-file#progress-meters-for-tasks-with-an-unknown-number-of-steps), which is precisely for your sort of problem, and includes spinner options.

---

<div class="post-metadata">

### Author: ![math\_opt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/math_opt/32/25317_2.png) [@math\_opt](https://discourse.julialang.org/u/math_opt)
#### Post date: [February 19, 2024, 1:38am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/3 "2024-02-19T01:38:38Z")

</div>

Thanks @stevengj. This is precisely what I tried but for this to work I still need some sort of loop. My code looks something like this:

```julia
function slow_function()
    sleep(10) #emulating complex calculation
end

function run()
    # progress/spinner display
    slow_function() #while this executes I display the spinner
   return
end

run()

```

Here, I don’t have any loop (so the `ProgressUnknown` function would still not work). Please let me know if I am missing something here and could somehow still use the ProgressMeter.jl package. Thanks!

---

<div class="post-metadata">

### Author: ![math\_opt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/math_opt/32/25317_2.png) [@math\_opt](https://discourse.julialang.org/u/math_opt)
#### Post date: [February 19, 2024, 2:24am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/5 "2024-02-19T02:24:09Z")

</div>

Yes, that didn’t work. Again because there is no loop at all.

---

<div class="post-metadata">

### Author: ![dilumaluthge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dilumaluthge/32/29283_2.png) [@dilumaluthge](https://discourse.julialang.org/u/dilumaluthge)
#### Post date: [February 19, 2024, 2:24am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/6 "2024-02-19T02:24:31Z")

</div>

Yeah I realized it won’t work ☹

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [February 19, 2024, 2:58am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/7 "2024-02-19T02:58:03Z")

</div>

> [@math\_opt](#):
>
> This is precisely what I tried but for this to work I still need some sort of loop.

Looking at stevengj’s link, the examples show a loop because the `next!` call can occur gracefully at one point in each iteration, but you can also call `next!` in several places in your method. Reading the rest of the README, it looks like `next!` also works on progress types with a known number of steps, and this seems preferable because you manually determine how many times `next!` is called.

> [@math\_opt](#):
>
> ```julia
> function slow_function()
> sleep(10) #emulating complex calculation
> end
> 
> function run()
> # progress/spinner display
> slow_function() #while this executes I display the spinner
> 
> ```

I don’t think progress indication can occur independently of the method. The `@showprogress` macro transforms expressions to include steps indicating the progress. Hypothetically you could run a timer totally independently of the method, but it cannot know where the method is when it reports a time, so it cannot serve as a progress indicator. I think it would have to look like:

```julia
function slow_progress()
   p = Progress(2; dt=1.0) # only call 2 times
   # do some stuff
   next!(p)
   # do more stuff
   next!(p)
   return
end

```

Ideally you space it out so you’re doing about the same amount of work between `next!` calls, so the progress increments mostly smoothly; that occurs often in loops of course. The `update!` function could be better if the amount of work varies quantifiably and can be worked into the increment.

---

<div class="post-metadata">

### Author: ![math\_opt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/math_opt/32/25317_2.png) [@math\_opt](https://discourse.julialang.org/u/math_opt)
#### Post date: [February 19, 2024, 3:05am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/8 "2024-02-19T03:05:24Z")

</div>

> [@Benny](#):
>
> ```julia
> function slow_progress()
> p = Progress(2; dt=1.0) # only call 2 times
> # do some stuff
> next!(p)
> # do more stuff
> next!(p)
> return
> end
> 
> ```

This makes sense. The only problem is that `slow_function` is imported from a different package and I have no control over it (in terms of modifying it). I assume there is no other way so far. But thanks for the reasoning behind `next!`, I can at least use it in functions written by me. Thanks!

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [February 19, 2024, 3:12am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/9 "2024-02-19T03:12:47Z")

</div>

> [@math\_opt](#):
>
> The only problem is that `slow_function` is imported from a different package and I have no control over it

That’s unfortunate. Since the method doesn’t indicate its progress or some measure of how close it is to ending, the best you can do is log how long each call takes and report the statistics prior to the next calls. If runtime varies over input size in a predictable way (like a bigger file or more files), you could model it. Hopefully the model was accurate enough to be a good predictor with enough data. None of the timing statistics tells you about the progress, just like how progress can’t tell you how long any increment would take, but at least you have nonzero information about how long your lunchbreak can be.

---

<div class="post-metadata">

### Author: ![math\_opt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/math_opt/32/25317_2.png) [@math\_opt](https://discourse.julialang.org/u/math_opt)
#### Post date: [February 19, 2024, 3:17am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/10 "2024-02-19T03:17:38Z")

</div>

That’s a nice workaround. Also, I am not really interested in showing the exact progress. I understand it can vary based on the input and difficult to track in this case. Hence, I am looking more at some sort of `spinner` that can be displayed (may be rotate every one second) while the function runs and stops once the function is executed. I can use your idea of average statistics to display beside the rotating spinner. The whole idea is to not make the screen look as if it’s stuck and not doing anything.

---

<div class="post-metadata">

### Author: ![screw\_dog](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/screw_dog/32/48119_2.png) [@screw\_dog](https://discourse.julialang.org/u/screw_dog)
#### Post date: [February 19, 2024, 3:45am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/11 "2024-02-19T03:45:27Z")

</div>

Something like this should work:

```julia
using ProgressMeter

slow_function() = sleep(10)

p = ProgressUnknown(; spinner=true)
channel = Channel() do ch
    while !isready(ch)
        next!(p)
        sleep(1)
    end
end;
slow_function()
close(channel)

```

It just spawns a thread to spin the progress meter every second and then stops it (by closing the channel) once the function has returned.

---

<div class="post-metadata">

### Author: ![math\_opt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/math_opt/32/25317_2.png) [@math\_opt](https://discourse.julialang.org/u/math_opt)
#### Post date: [February 19, 2024, 3:52am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/12 "2024-02-19T03:52:25Z")

</div>

This is great! Thanks. However the progress meter keeps running even after the `close(channel)`.

---

<div class="post-metadata">

### Author: ![screw\_dog](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/screw_dog/32/48119_2.png) [@screw\_dog](https://discourse.julialang.org/u/screw_dog)
#### Post date: [February 19, 2024, 3:59am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/13 "2024-02-19T03:59:21Z")

</div>

Oops!

Try this instead:

```julia
using ProgressMeter

slow_function() = sleep(3)

p = ProgressUnknown(; spinner=true)
channel = Channel() do ch
    while !isready(ch)
        next!(p)
        sleep(1)
    end
    take!(ch)
end;
slow_function()
put!(channel, 1)

```

---

<div class="post-metadata">

### Author: ![math\_opt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/math_opt/32/25317_2.png) [@math\_opt](https://discourse.julialang.org/u/math_opt)
#### Post date: [February 19, 2024, 4:04am UTC](https://discourse.julialang.org/t/spinner-progress-meter-for-slow-functions/110385/14 "2024-02-19T04:04:12Z")

</div>

Perfect! Thanks!
