djberg96 / sys-proctable

A cross-platform Ruby interface for gathering process information on your operating system
Apache License 2.0
150 stars 33 forks source link

Linux version is slow when reading all processes smaps #64

Closed ZaWertun closed 6 years ago

ZaWertun commented 7 years ago

Please add option that allows to skip reading process smap on Linux.

I do some time measurements. File ps.rb:

require 'sys/proctable'
Sys::ProcTable.ps

With smaps:

$ time ruby ps.rb 
5.53user 0.42system 0:05.97elapsed 99%CPU (0avgtext+0avgdata 18588maxresident)k
0inputs+0outputs (0major+7071minor)pagefaults 0swaps

Without smaps reading:

$ time ruby ps.rb 
0.31user 0.05system 0:00.37elapsed 99%CPU (0avgtext+0avgdata 11256maxresident)k
0inputs+0outputs (0major+4656minor)pagefaults 0swaps

So script executes 16x times faster.

ZaWertun commented 7 years ago

Also I noticed that script ps.rb runs almost 2x slower on Ruby version 2.4.2 vs version 2.1.2.

$ rbenv global 2.4.2; time ruby ps.rb 
5.56user 0.42system 0:06.02elapsed 99%CPU (0avgtext+0avgdata 18916maxresident)k
0inputs+0outputs (0major+7745minor)pagefaults 0swaps
$ rbenv global 2.1.2; time ruby ps.rb 
2.63user 0.44system 0:03.09elapsed 99%CPU (0avgtext+0avgdata 30420maxresident)k
0inputs+0outputs (0major+9675minor)pagefaults 0swaps

:confused:

djberg96 commented 7 years ago

@ZaWertun Not sure what to say. All it's doing under the covers is:

smaps_contents = IO.read("/proc/#{file}/smaps") rescue ""
struct.smaps = Smaps.new(file, smaps_contents)

Is there anything in particular that was cause that to be so slow?

As for 2.4 vs 2.1, I'm afraid you'll have to take that up with the ruby-core team.

ZaWertun commented 7 years ago

Some details about Linux: Fedora 26 x86_64, kernel 4.13.7. Ruby version: ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux].

Script ps.rb modified for profiling:

require 'ruby-prof'
require 'sys/proctable'

result = RubyProf.profile do
    Sys::ProcTable.ps
end

printer = RubyProf::GraphPrinter.new(result)
printer.print(STDOUT, {})

Script output: ps-perf.log

Also I will check execution time of the script on other computer with the same software configuration.

ZaWertun commented 7 years ago

Other machine is not that slow as first. But still I have execution time more than 1 sec. (for 204 processes).

$ time ruby ps.rb 
time ruby ps.rb 
1.44user 0.19system 0:01.63elapsed 99%CPU (0avgtext+0avgdata 17788maxresident)k
0inputs+0outputs (0major+8056minor)pagefaults 0swaps

Output of running ruby ps-perf.rb > ps-perf.log: ps-perf.log

ZaWertun commented 7 years ago

I've got worst case on server with Oracle Linux Server 7.2 running Oracle DB (and having ~160 GB RAM).

$ time ruby ps.rb 

real    1m50.405s
user    1m23.792s
sys     0m26.429s

Yep, script runs for almost 2 min.

djberg96 commented 7 years ago

It's taking 1m50s real time to do a single read?! What's the total number of processes?

ZaWertun commented 7 years ago

There is 118 processes running. Single read is not slow, but total size of all smaps read is really huge:

$ cat /proc/*/smaps > smaps.log
$ du -h smaps.log
1.5G    smaps.log
djberg96 commented 7 years ago

Ooh boy. Well, I want to keep the interface universal across platforms, so I'll have to think about how to handle this.

djberg96 commented 6 years ago

@ZaWertun Note that you can reduce memory usage by using a block, though it will slow it down, e.g. Sys::ProcTable.ps { |process| # your logic here }. That will yield each result one at a time instead of collecting them into an array.

I don't know if it's an option, but there you go.

djberg96 commented 6 years ago

I don't know if it will matter, but I should probably change the one line to:

smaps_contents = IO.read("/proc/#{file}/smaps", Smaps.size) rescue ""

djberg96 commented 6 years ago

@ZaWertun We're altering the API for version 1.2, which I hope to have out within the next week. Instead of a single argument, it will now allow you to govern some of the behavior. So, you'll be able to do this:

Sys::ProcTable.ps(smaps: false), and it won't collect smaps information.

ZaWertun commented 6 years ago

Thanks! 😊

ZaWertun commented 6 years ago

I'm closing issue.