Project

General

Profile

Feature #11952

Use getrusage for Process.times if available

Added by k0kubun (Takashi Kokubun) almost 4 years ago. Updated over 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-dev:49471]

Description

Since times(3) has poor precision, I want to use getrusage(2) for Process.times to get better precision if getrusage is available.

before: Process.times #=> #
after: Process.times #=> #


Files

Associated revisions

Revision 253232c0
Added by k0kubun (Takashi Kokubun) over 2 years ago

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

Revision 58935
Added by k0kubun (Takashi Kokubun) over 2 years ago

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]

Revision 58935
Added by k0kubun (Takashi Kokubun) over 2 years ago

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]

Revision 58935
Added by k0kubun (Takashi Kokubun) over 2 years ago

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]

History

Updated by k0kubun (Takashi Kokubun) almost 4 years ago

Oops, my description is unexpectedly removed ...

I meant:

before: Process.times #=> #<struct Process::Tms utime=0.06, stime=0.02, cutime=0.02, cstime=0.03>
after: Process.times #=> #<struct Process::Tms utime=0.066553, stime=0.026196, cutime=0.024421, cstime=0.03303>

Updated by k0kubun (Takashi Kokubun) over 2 years ago

Does anyone have opinion about this? Can I commit this?

I think it would be good to apply this patch to improve lib/benchmark.rb's precision.

Updated by akr (Akira Tanaka) over 2 years ago

It seems fine.

Actually, times(3) is implemented using getrusage(2) on NetBSD.
http://cvsweb.netbsd.org/cgi-bin/cvsweb.cgi/src/lib/libc/gen/times.c?rev=1.15&content-type=text/x-cvsweb-markup

Also, times(2) seems to obtain same result of getrusage(2) on Linux.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/sys.c

#4

Updated by k0kubun (Takashi Kokubun) over 2 years ago

  • Status changed from Open to Closed

Applied in changeset trunk|r58935.


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
=> #<struct Process::Tms utime=0.56, stime=0.35, cutime=0.04, cstime=0.03>

puts Benchmark.measure { "a" * 1_000_000_000 }
  0.340000   0.310000   0.650000 (  0.674025)
  • After
Process.times
=> #<struct Process::Tms utime=0.561899, stime=0.35076, cutime=0.046483, cstime=0.038929>

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
=> #<struct Process::Tms utime=0.43, stime=0.11, cutime=0.0, cstime=0.0>

puts Benchmark.measure { "a" * 1_000_000_000 }
  0.120000   0.040000   0.170000 (  0.171621)
  • After
Process.times
=> #<struct Process::Tms utime=0.432, stime=0.116, cutime=0.0, cstime=0.0>

puts Benchmark.measure { "a" * 1_000_000_000 }
  0.124000   0.048000   0.172000 (  0.171621)

[ruby-dev:49471] [Feature #11952]

Also available in: Atom PDF