Closed ZaWertun closed 6 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:
@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.
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.
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
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.
It's taking 1m50s real time to do a single read?! What's the total number of processes?
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
Ooh boy. Well, I want to keep the interface universal across platforms, so I'll have to think about how to handle this.
@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.
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 ""
@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.
Thanks! 😊
I'm closing issue.
Please add option that allows to skip reading process smap on Linux.
I do some time measurements. File
ps.rb
:With smaps:
Without smaps reading:
So script executes 16x times faster.