--- name: times signature: 'times' since: 5.0 status: documented categories: ["Processes", "Time"] --- ```{index} single: times; Perl built-in ``` *[Processes](../perlfunc-by-category) · [Time](../perlfunc-by-category)* # times Report CPU time consumed by this process and its terminated children. `times` asks the kernel how many seconds of user-mode and kernel-mode CPU have been charged to the current process, and — separately — to children that have already been reaped. The return is four floating- point seconds: user, system, child-user, child-system. It answers "how much CPU have I burned?", not "how much wall-clock time has passed?" — for that, see [`time`](time). ## Synopsis ```perl my ($user, $system, $cuser, $csystem) = times; my $user_only = times; # scalar context ``` ## What you get back In list context, four values: - `$user` — CPU time spent in user-mode code of this process. - `$system` — CPU time spent in the kernel on behalf of this process. - `$cuser` — user-mode CPU time of **terminated** child processes. - `$csystem` — kernel-mode CPU time of **terminated** child processes. All four are seconds as double-precision floats; resolution is microsecond on Linux (sourced from `getrusage`). In scalar context, `times` returns just `$user`. `times` takes no arguments and cannot fail in a way visible to the caller. ## Children's times — the "terminated" rule `$cuser` and `$csystem` aggregate CPU only from children that have been **reaped** — i.e. a [`wait`](wait) or [`waitpid`](waitpid) has successfully collected their exit status, or they were autoreaped because `$SIG{CHLD}` was set to `'IGNORE'`. A child that is still running, or has exited but not yet been reaped (a zombie), contributes nothing. This matters when measuring a pipeline that spawns workers: ```perl my $pid = fork; if ($pid == 0) { do_work(); exit } # (busy child runs here) my ($u0, $s0, $cu0, $cs0) = times; # $cu0, $cs0 still 0 waitpid($pid, 0); my ($u1, $s1, $cu1, $cs1) = times; # now $cu1, $cs1 reflect child ``` Until the `waitpid` returns, the child's CPU does not appear in the parent's `times`. ## Examples Measure CPU cost of a block of work, excluding wall-clock sleeps or I/O waits: ```perl my ($u0, $s0) = times; compute_heavy(); my ($u1, $s1) = times; printf "compute used %.3f s user + %.3f s system\n", $u1 - $u0, $s1 - $s0; ``` Compare CPU time to wall-clock time — a low ratio means the process was mostly waiting rather than computing: ```perl use Time::HiRes qw(time); my $t0 = time; my ($u0, $s0) = times; do_mixed_io_and_compute(); my $wall = time - $t0; my ($u1, $s1) = times; printf "cpu/wall = %.2f\n", ($u1 - $u0 + $s1 - $s0) / $wall; ``` Attribute a parallel workload to its children. Reap every child before reading `times`: ```perl my @pids = map { my $p = fork; $p == 0 ? (worker($_), exit) : $p } 1..4; waitpid($_, 0) for @pids; my (undef, undef, $cu, $cs) = times; printf "workers used %.2f s user + %.2f s system\n", $cu, $cs; ``` Scalar context when only the user time matters — e.g. a quick self-profiling print: ```perl printf STDERR "[%.2f] reached checkpoint\n", scalar times; ``` ## Edge cases - **No arguments, no prototype to worry about.** `times` is a zero-argument built-in; `times()` and `times` parse identically. It is **not** the transliteration operator — that is `tr///` (alias `y///`), which is a separate token. - **Scalar vs list context is load-bearing.** Writing `my $t = times;` binds `$user` to `$t`, discarding the other three values silently. Use `my ($u,$s,$cu,$cs) = times;` when you want them all. - **Unreaped children don't count.** See the "terminated" rule above. Reading `times` before `wait` gives `$cuser == $csystem == 0` even when the child is visibly burning CPU in `top`. - **Threads do count.** On Linux, kernel-threaded work in the current process shows up in `$user` / `$system` just like single-threaded work. Threads in a separate process don't, until that process exits and is reaped. - **Clock is monotonic-within-process, not wall-clock.** `times` never goes backwards across a single process's lifetime, but successive `times` calls are not directly comparable between parent and child — each `getrusage` accounting is local. - **Resolution.** Linux reports microsecond-resolution ticks via `getrusage`, so short measurements (sub-millisecond) are noisy but not zero. For high-precision wall-clock timing, use `Time::HiRes::time`, not `times`. - **Overflow.** Values are floats; they can in principle lose sub-microsecond precision after very long runs (years of CPU), but this is not a concern for normal programs. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`time`](time) — wall-clock seconds since the epoch; use it when you want elapsed real time, not CPU time - `Time::HiRes::time` — high-resolution wall-clock time, the usual partner for CPU accounting - [`POSIX::times`](../../POSIX/times) — POSIX wrapper returning an additional real-time "clock ticks since boot" value; use it when you need the elapsed field the built-in omits - [`wait`](wait) — reap a child so its CPU starts counting in `$cuser` / `$csystem` - [`waitpid`](waitpid) — reap a specific child for the same reason, without blocking on unrelated ones - [`fork`](fork) — the operation whose cost shows up in the child columns once the child is reaped