4
\$\begingroup\$

I have made this program to simulate polybar's bspwm module. So far, it works flawlessly; however, it consumes too much RAM and CPU (16-30%). I suspect it is the while loop causing the trouble, but what can be done to reduce resource usage?

use strict;
use warnings;
use Switch;
use List::MoreUtils qw(first_index);
$SIG{INT}=sub{ die "goodnight !\n $!"; };
my $underline='#ffffff';
my $default_background='#51002f';
my $default_workspace_background='#727272';
my $default_workspace_foreground='#ffffff';
my $default_foreground='#ffffff';
my $focussed_background='#000000';
my $focussed_foreground='#ffffff';
my $occupied_background='#3a3a3a';
my $occupied_foreground='#ffffff';
my @desktops=qx/ bspc query -D /;
my @lemonbar_array=();
my $lemonbar_string="%{B$default_background}%{F$default_foreground}%{+u}  0x00400004 %{-u}%{B-}%{F-}";
my $date_string="%{c}%{B$focussed_background}%{F$default_foreground}%{+u} %date %{-u}%{B-}%{F-}";
my $add_this="%{+u}%{B$default_background}%{F$default_foreground} %{A:firefox:} web %{A} %{B-}%{F-} %{B$default_background}%{F$default_foreground} %{A:evince:} pdf %{A} %{B-}%{F-} %{B$default_background}%{F$default_foreground} %{A:libreoffice:} doc %{A} %{B-}%{F-} %{B$default_background}%{F$default_foreground} %{A:firefox youtube.com:} youtube %{A} %{B-}%{F-} %{B$default_background}%{F$default_foreground} %{A:firefox netflix.com:} netflix %{A} %{B-}%{F-} %{B$default_background}%{F$default_foreground} %{A:firefox gmail.com:} gmail %{A} %{B-}%{F-} %{B$default_background}%{F$default_foreground} %{A:firefox protonmail.com:} protonmail %{A} %{B-}%{F-} %{B$default_background}%{F$default_foreground} %{A:nautilus:} files %{A} %{B-}%{F-} %{B$default_background}%{F$default_foreground} %{A:urxvt:} terminal %{A} %{B-}%{F-}%{-u}";
for(my $i=0;$i<=9;$i++){ 
 push(@lemonbar_array,$lemonbar_string); 
}
my $current_monitor='';
while() { 
 my $date=gmtime();
 $date_string=~s/%date/$date/;
 $current_monitor=qx/bspc query -D -d/;
 my $index_current_monitor=first_index { $_ eq $current_monitor } @desktops;
 my $index_print=$index_current_monitor+1;
 $lemonbar_array[$index_current_monitor]=~s/(?<=B)#.{6}/$focussed_background/;
 $lemonbar_array[$index_current_monitor]=~s/(?<=F)#.{6}/$focussed_foreground/;
 $lemonbar_array[$index_current_monitor]=~s/0x00.{6}/$index_print/;
 for(my $i=0;$i<10;$i++){
 if($desktops[$i] ne $current_monitor){
 my $i1=$i+1;
 $lemonbar_array[$i]=~s/0x00.{6}/$i1/;
 if(scalar(my @n=qx/bspc query -N -d $desktops[$i]/) gt 0){ 
 $lemonbar_array[$i]=~s/(?<=B)#\w{6}/$occupied_background/;
 $lemonbar_array[$i]=~s/(?<=F)#\w{6}/$occupied_foreground/;
 }
 else{
 $lemonbar_array[$i]=~s/(?<=B)#\w{6}/$default_workspace_background/;
 $lemonbar_array[$i]=~s/(?<=F)#\w{6}/$default_workspace_foreground/;
 }
 }
 }
 
 print "%{l}@lemonbar_array $date_string %{r}$add_this\n";
}
toolic
15.2k5 gold badges29 silver badges213 bronze badges
asked Oct 26, 2018 at 8:14
\$\endgroup\$
1
  • 1
    \$\begingroup\$ As for cpu, cut down number of shell calls per minute. \$\endgroup\$ Commented Oct 27, 2018 at 18:52

1 Answer 1

3
\$\begingroup\$

Overview

It is great that you:

  • Used strict and warnings
  • Leveraged other people's code by using the List::MoreUtils module
  • Minimized namespace population by importing only needed functions
  • Used meaningful names for variables

Performance

It is wasteful to execute these lines inside the while loop:

my $date=gmtime;
$date_string=~s/%date/$date/;

The substitution only happens once during the first time though the loop. That is when the literal %date string is replaced with the return value of gmtime. Every other time thorough the loop, the match never occurs.

Before the loop, store the return value from gmtime, then interpolate it directly into the $date_string, rather than doing a substitution with s///:

my $date = gmtime;
my $date_string = "%{c}%{B$focussed_background}%{F$default_foreground}%{+u} $date %{-u}%{B-}%{F-}";

Unused code

Remove this line:

use Switch;

The module is not used, and it is notorious for causing problems.

DRY

Since you execute this external command several times, store it in a variable:

 my $cmd = 'bspc query ';

Be explicit

The while has an empty expression:

while()

Although it is documented that this results in an infinite loop, it is not obvious when looking at the code. It is clearer to use 1 as the expression:

while (1)

Perlish

It is considered more "Perlish" to use map instead of the for/push combination for simple code:

my @lemonbar_array=();
for(my $i=0;$i<=9;$i++){ 
 push(@lemonbar_array,$lemonbar_string); 
}

Consider this instead:

my @lemonbar_array = map { $lemonbar_string } 1 .. 10;

Also, instead of the C-style for loop:

for(my $i=0;$i<10;$i++){

Consider this instead:

for my $i (0 .. 9) {

Long line

Long lines are hard to understand and maintain. This should be broken up:

my $add_this="%{+u}%{B$default_background}%{F$default_foreground} %{A:firefox:} ...

Whitespace

Add a single space before and after these operators for better readability: = and =~. perltidy can be used to add consistent formatting to your code.

Delete the extra blank lines in the inner for loop.

 else{
 $lemonbar_array[$i]=~s/(?<=B)#\w{6}/$default_workspace_background/;
 $lemonbar_array[$i]=~s/(?<=F)#\w{6}/$default_workspace_foreground/;
 }

Linting

perlcritic identifies some issues.

Trailing whitespace is unnecessary and can be annoying. It should be removed.

Don't use parentheses with built-in functions like gmtime.

Documentation

Consider adding some usage notes at the top of the file as plain old documentation (POD), something as simple as:

=pod
Simulate polybar's bspwm module.
=cut
answered Mar 10, 2024 at 0:40
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.