From 253232c028a5565dbeecc05fab5e81b35ab58bcc Mon Sep 17 00:00:00 2001 From: k0kubun Date: Sun, 28 May 2017 01:48:11 +0000 Subject: [PATCH] process.c: Use getrusage(2) in Process.times if getrusage(2) is available, to improve precision of Process.times and its user like lib/benchmark.rb. On macOS, since getrusage(2) has better precision than times(3), they are much improved like: * Before Process.times => # puts Benchmark.measure { "a" * 1_000_000_000 } 0.340000 0.310000 0.650000 ( 0.674025) * After Process.times => # puts Benchmark.measure { "a" * 1_000_000_000 } 0.343223 0.310037 0.653260 ( 0.674025) On Linux, since struct rusage from getrusage(2) is used instead of struct tms from times(2), they are slightly improved like: * Before Process.times => # puts Benchmark.measure { "a" * 1_000_000_000 } 0.120000 0.040000 0.170000 ( 0.171621) * After Process.times => # puts Benchmark.measure { "a" * 1_000_000_000 } 0.124000 0.048000 0.172000 ( 0.171621) [ruby-dev:49471] [Feature #11952] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58935 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- NEWS | 4 ++++ process.c | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5bfe01b3a0..3f9f620850 100644 --- a/NEWS +++ b/NEWS @@ -59,6 +59,10 @@ with all sufficient information, see the ChangeLog file or Redmine of #coerce. Return nil in #coerce if the coercion is impossible. [Feature #7688] +* Process + + * Precision of Process.times is improved if getrusage(2) exists. [Feature #11952] + * Range * Range#initialize no longer rescue exceptions when comparing begin and end with #<=> and raise a "bad value for range" ArgumentError diff --git a/process.c b/process.c index c8964dff69..67f51db847 100644 --- a/process.c +++ b/process.c @@ -6887,15 +6887,26 @@ get_clk_tck(void) VALUE rb_proc_times(VALUE obj) { + VALUE utime, stime, cutime, cstime, ret; +#if defined(RUSAGE_SELF) && defined(RUSAGE_CHILDREN) + struct rusage usage_s, usage_c; + + if (getrusage(RUSAGE_SELF, &usage_s) != 0 || getrusage(RUSAGE_CHILDREN, &usage_c) != 0) + rb_sys_fail("getrusage"); + utime = DBL2NUM((double)usage_s.ru_utime.tv_sec + (double)usage_s.ru_utime.tv_usec/1e6); + stime = DBL2NUM((double)usage_s.ru_stime.tv_sec + (double)usage_s.ru_stime.tv_usec/1e6); + cutime = DBL2NUM((double)usage_c.ru_utime.tv_sec + (double)usage_c.ru_utime.tv_usec/1e6); + cstime = DBL2NUM((double)usage_c.ru_stime.tv_sec + (double)usage_c.ru_stime.tv_usec/1e6); +#else const double hertz = get_clk_tck(); struct tms buf; - VALUE utime, stime, cutime, cstime, ret; times(&buf); utime = DBL2NUM(buf.tms_utime / hertz); stime = DBL2NUM(buf.tms_stime / hertz); cutime = DBL2NUM(buf.tms_cutime / hertz); cstime = DBL2NUM(buf.tms_cstime / hertz); +#endif ret = rb_struct_new(rb_cProcessTms, utime, stime, cutime, cstime); RB_GC_GUARD(utime); RB_GC_GUARD(stime);