From: Brian Candler Date: 2008-11-11T21:56:11+09:00 Subject: Re: How to optimize my ruby code Valentino Lun 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. -- Posted via http://www.ruby-forum.com/.