Skip to content
This repository has been archived by the owner on Nov 11, 2018. It is now read-only.

Optimize ps termlet. Runs in ~1.3sec instead of ~2sec on an AMD E-350. #340

Merged
merged 6 commits into from
Aug 24, 2014
8 changes: 6 additions & 2 deletions data/Termlets/ls
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
#!/bin/bash

ls_output=$(ls "$@")
dir_begin_mark=$(text_menu_start '2')
dir_end_mark=$(text_menu_end '2')
file_begin_mark=$(text_menu_start '1')
file_end_mark=$(text_menu_end '1')

# Surround with additional newlines to facilitate matching (see below)
ls_output=$'\n'$ls_output$'\n'

# TODO: Search for files in directory passed to ls rather than the current directory
for filename in *; do
if [[ -d $filename ]]; then
file_substitution="$(text_menu_start '2')$filename$(text_menu_end '2')"
file_substitution="$dir_begin_mark$filename$dir_end_mark"
else
file_substitution="$(text_menu_start '1')$filename$(text_menu_end '1')"
file_substitution="$file_begin_mark$filename$file_end_mark"
fi

# Short format ("ls"; each filename on a single line)
Expand Down
40 changes: 21 additions & 19 deletions data/Termlets/ps
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
#!/bin/bash

ps "$@" |

while IFS= read -r line; do
# Position of string "PID" in line
pid_index=$(awk -v a="$line" -v b='PID' 'BEGIN{print index(a,b)}')

if [[ "$pid_index" -gt 0 ]]; then
# Header line
pid_end=$(($pid_index + 3))
modified_line="$line"
else
# Content line
left_part=${line:0:pid_end-1}
pid_part=${left_part##* }
# Remove pid_part from left_part
left_part=${left_part:0:${#left_part}-${#pid_part}}
right_part=${line:pid_end-1}
modified_line="$left_part$(text_menu_start '3')$pid_part$(text_menu_end '3')$right_part"
fi
# IFS is '\n'
IFS=$'\012'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe bash will actually recognize IFS='\n' directly

psoutput=($(ps "$@"))
# Just in case PPID could be displayed before PID, search for ' PID'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it ever possible that "PID" stands at the beginning of the line, or is preceded by a tab rather than space? If yes, this could fail...

pid_index=$(awk -v a="${psoutput[0]}" -v b=' PID' 'BEGIN{print index(a,b)}')
# don’t use $() in loops, as it spawns a sub-process, so get markings out of the loop.
begin_mark=$(text_menu_start '3')
end_mark=$(text_menu_end '3')
# last character position of PID display.
let pid_end=pid_index+4
# display 1st line as is, then destroy it.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting idea. I like it!

echo -e ${psoutput[0]}
unset psoutput[0]

for line in ${psoutput[@]}; do
# Content line
left_part=${line:0:${pid_end}-1}
pid_part=${left_part##* }
# Remove pid_part from left_part
left_part=${left_part:0:${#left_part}-${#pid_part}}
right_part=${line:pid_end-1}
modified_line="$left_part$begin_mark$pid_part$end_mark$right_part"
echo -e "$modified_line"
done
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tested this extensively and noticed a speedup of at least a factor of 20. Great stuff!