# How to optimize my ruby code

**URL:** <https://www.ruby-forum.com/t/how-to-optimize-my-ruby-code/153043>\
**Category:** Ruby\
**Created:** [November 11, 2008, 1:39pm UTC](https://www.ruby-forum.com/t/how-to-optimize-my-ruby-code/153043 "2008-11-11T13:39:07Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![on9west](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/6f9a4e/32.png) [@on9west](https://www.ruby-forum.com/u/on9west)\
**Post date:** [November 11, 2008, 1:39pm UTC](https://www.ruby-forum.com/t/how-to-optimize-my-ruby-code/153043/1 "2008-11-11T13:39:07Z")

</div>

I am writing a script to get the process image in unix through ssh, then  
insert the record to database. As I am a new ruby user, I think my  
method is quite stupid and I would like to know if you can make my code  
prettier. Thanks.

Below is the ps image in my unix server (command : ps auxww)  
USER PID %CPU %MEM SZ RSS TTY STAT STIME TIME COMMAND  
\n  
testrrs1 2429158 0.0 0.0 15588 15624 - A 13:27:12 0:00 java  
lis.rpt.PostPrtMain /appl/lis/home2/testrrs1/config/PPRT\_3.att \n  
testlib 2425018 0.0 0.0 3052 4772 - A May 29 0:00  
/appl/lis/home/lib/test/work/rls\_server -i/appl/lis/home/lib/test/w \n

====start of script===  
require “rubygems”  
$LOADED\_FEATURES[$LOADED\_FEATURES.length] =  
‘net/ssh/authentication/pageant.rb’  
require ‘net/ssh’  
require “active\_record”  
$config = YAML.load\_file(File.join(File.dirname( **FILE** ),  
‘database.yml’))

ssh=Net::SSH.start(“hostname”, “account”, :port =\> 12345, :paranoid =\>  
false, :auth\_methods =\> [“publickey”], :passphrase =\> “testing”, :keys  
=\> [“C:/testing/id\_rsa”])

ps=ssh.exec!(“ps auxww | head -30”)  
ssh.close

ps=ps.to\_a  
for idx in (0…ps.length)  
next if idx==0 #skip the header  
ps\_user=ps[idx].split[0]  
ps\_pid=ps[idx].split[1]  
ps\_cpu=ps[idx].split[2]  
ps\_mem=ps[idx].split[3]  
ps\_sz=ps[idx].split[4]  
ps\_rss=ps[idx].split[5]  
ps\_tty=ps[idx].split[6]  
ps\_stat=ps[idx].split[7]

# The STIME field may equal to May 29 or 13:27:12, and the COMMAND

has unknown number of space.  
if (ps[idx].split[8].include?(":"))  
ps\_stime=ps[idx].split[8]  
ps\_cmd=ps[idx].split[9]+" “+ps[idx].split[10]+” “+ … +  
ps[idx].split[ps[idx].length]  
else  
ps\_stime=ps[idx].split[8]+” “+ps[idx].split[9]  
ps\_cmd=ps[idx].split[10]+” “+ps[idx].split[11]+” "+ … +  
ps[idx].split[ps[idx].length]  
end

MyTable.create(:ps\_user =\> ps\_user, :ps\_pid =\> ps\_pid, …SKIP…  
:ps\_cmd =\> ps\_cmd)

end

====end of script===

Thank you very much for your kind assistance.

---

<div class="post-metadata">

**Author:** ![on9west](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/6f9a4e/32.png) [@on9west](https://www.ruby-forum.com/u/on9west)\
**Post date:** [November 11, 2008, 1:58pm UTC](https://www.ruby-forum.com/t/how-to-optimize-my-ruby-code/153043/2 "2008-11-11T13:58:46Z")

</div>

Valentino L. wrote:

> ps=ps.to\_a  
> for idx in (0…ps.length)

This is fine since you use idx later on to skip the first line, although  
an alternative is

ps.to\_a.each\_with\_index do |line, idx|

> next if idx==0 #skip the header  
> ps\_user=ps[idx].split[0]  
> ps\_pid=ps[idx].split[1]  
> ps\_cpu=ps[idx].split[2]  
> ps\_mem=ps[idx].split[3]  
> ps\_sz=ps[idx].split[4]  
> ps\_rss=ps[idx].split[5]  
> ps\_tty=ps[idx].split[6]  
> ps\_stat=ps[idx].split[7]

user, pid, cpu, mem, sz, rss, tty, stat, \*rest = line.split

> # The STIME field may equal to May 29 or 13:27:12, and the COMMAND
> 
> has unknown number of space.  
> if (ps[idx].split[8].include?(":"))  
> ps\_stime=ps[idx].split[8]  
> ps\_cmd=ps[idx].split[9]+" “+ps[idx].split[10]+” “+ … +  
> ps[idx].split[ps[idx].length]  
> else  
> ps\_stime=ps[idx].split[8]+” “+ps[idx].split[9]  
> ps\_cmd=ps[idx].split[10]+” “+ps[idx].split[11]+” "+ … +  
> ps[idx].split[ps[idx].length]  
> end

if rest[0].include?(":")  
stime, cmd = rest[0], rest[1…-1].join(" “)  
else  
stime, cmd = rest[0]+” “+rest[1], rest[2…-1].join(” ")  
end

But a shorter (and still very efficient) way is to write a big Regexp  
for matching all this:

PS\_LINE = %r{^  
(\S+) \s+ # user  
(\S+) \s+ # pid  
(\S+) \s+ # cpu  
(\S+) \s+ # mem  
(\S+) \s+ # sz  
(\S+) \s+ # rss  
(\S+) \s+ # tty  
(\S+) \s+ # stat  
(\d\d:\d\d:\d\d | \w\w\w\s\d\d) \s+ # stime  
(.\*) # cmd  
$}x

ps.each\_line do |line|  
if PS\_LINE =~ line  
MyTable.create(:ps\_user =\> $1, :ps\_pid =\> $2, …SKIP…  
:ps\_cmd =\> $10)  
end  
end

The ‘x’ flag to a Regexp lets you embed spaces and comments to make it  
more readable. You can tweak it to match the data more precisely, e.g.  
use (\d+) instead of (\S+) to match the pid, so that any unexpected  
lines are ignored.

---

<div class="post-metadata">

**Author:** ![on9west](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/6f9a4e/32.png) [@on9west](https://www.ruby-forum.com/u/on9west)\
**Post date:** [November 11, 2008, 2:33pm UTC](https://www.ruby-forum.com/t/how-to-optimize-my-ruby-code/153043/3 "2008-11-11T14:33:12Z")

</div>

Thank you for your clear explanation. I think I learned a great lesson.
