greshake / i3status-rust

Very resourcefriendly and feature-rich replacement for i3status, written in pure Rust
GNU General Public License v3.0
2.82k stars 472 forks source link

Questions regarding resource usage optimizations #1921

Open Delgan opened 1 year ago

Delgan commented 1 year ago

Hi!

I was wondering about possible optimizations made or not by i3status-rust, to be as "resource-friendly" as possible.

Let's take this example configuration:

[theme]
theme = "solarized-dark"

[icons]
icons = "awesome4"

[[block]]
block = "time"
format = " ^icon_calendar $timestamp.datetime(f:'%F') "
interval = 5

[[block]]
block = "time"
format = " ^icon_time $timestamp.datetime(f:'%R') "
interval = 5
  1. I can see that even if both blocks have the same interval value, i3status-rs emit two messages every 5 seconds. I would expect a single message to be sent every 5 seconds. I assume this is because calls are async, correct?
  2. I observe that even if the output does not change, i3status-rs still sends a message. However, there will be nothing to re-render on the bar since nothing has changed. Why send a message anyway?
  3. In the example, I have two blocks that relies on the same time resource. I imagine that the time will be requested twice, whereas once would have been sufficient, to then update the format only. Is it possible to derive one block from another to reduce redundant calls (while keeping the blocks separate, and assigning them different click events)?
  4. There exists yambar with goals similar to i3status-rust regarding resource-friendliness. It does some clever tricks for optimization reasons, such as updating the clock only once per minute while preserving accuracy. Is this something that has been considered by i3status-rust?

Thanks.

MaxVerevkin commented 1 year ago

Great questions!

  1. Yes, this is because blocks are asynchronous. Although it would be really nice to implement this optimization, but it really only works for "non-blocking" blocks, such as time, memory, disk_space, etc. I suppose we can have two kinds of blocks:
    • Async - they implement async fn run() function and manage timing themselves. Basically those that deal with web requests, run external programs or use some notification system such as dbus or IPC (backlight, sound, etc.). This optimization cannot be applied to them. Right now all block are async.
    • Non-blocking - they expose a struct which implements a trait with a few functions, mainly render(&self) -> Vec<I3BarBlock> or something similar. Then the scheduling is performed outside of the block. This is basically the design of i3status-rs prior to async rewrite. Works great for simple blocks which just display some information and don't need to manage complex internal state.
    It would be neat to have a hard separation between these two types of blocks, but some blocks can be either depending on the configuration or runtime environment (e.g. keyboard_layout or hueshift). I can imagine every block starting as an async one, and then some blocks can become "non-blocking" by sending an appropriate message.
  2. This can be implemented fairly simply, sure.
  3. It is possible and some blocks do this. In particular, you can have any number of sound blocks in your bar in any order and they all use the same pulseaudio connection. In case of time it isn't as important since fetching time is a pretty cheap operation.
  4. This particular optimization was proposed (#111) but no one implemented it.
Delgan commented 1 year ago

Thanks for your prompt and detailed reply, @MaxVerevkin!

This clarifies my understanding of how i3status-rust works.

I don't know how useful these possible improvements would be in practice, probably not very much. It was mainly curiosity. Feel free to close this ticket then (unless these improvements are of interest to the project). :+1:

MaxVerevkin commented 10 months ago

Feel free to close this ticket then (unless these improvements are of interest to the project)

I do wish to implement "non blocking" or "stateless" blocks at some point, so I'll leave this open.