R Academy · Lesson

system.time() and proc.time()

Measure elapsed, user, and system time for R expressions.

Lesson 1 of 413 steps

system.time() and proc.time() is a free R Academy lesson on CoddyKit. This is lesson 1 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the R Academy learning path, and your progress syncs across the web and the CoddyKit app. The R Academy course includes 4 lessons in total.

Why Measure Performance?

Before optimizing code, you need to measure it. Guessing where slowness lives leads to wasted effort. R provides built-in tools to time expressions precisely.

The three main tools are system.time(), proc.time(), and Sys.time(). Each serves a different purpose in performance analysis.

system.time() Basics

system.time(expr) evaluates an expression and returns how long it took. It is the simplest way to time a single operation in R.

The result is an object of class proc_time with named elements you can inspect.

result <- system.time({
  x <- 1:1000000
  total <- sum(x)
})
print(result)

Reading the Three Time Values

system.time() returns five values, but three matter most:

  • user — CPU time used by R code itself
  • sys — CPU time used by the operating system on behalf of R
  • elapsed — wall-clock time (real seconds that passed)

Elapsed is usually what you care about. User + sys can exceed elapsed on multi-core machines.

t <- system.time(Sys.sleep(0.1))
cat('user   :', t['user.self'], '
')
cat('sys    :', t['sys.self'], '
')
cat('elapsed:', t['elapsed'], '
')

proc.time() for Manual Timing

proc.time() returns the current CPU and elapsed times as a snapshot. By capturing it before and after a block, you can time any arbitrary chunk of code.

Subtract the start snapshot from the end snapshot to get elapsed time for that section.

start <- proc.time()
for (i in 1:100000) sqrt(i)
end <- proc.time()
diff <- end - start
cat('elapsed:', diff['elapsed'], 'seconds
')

proc.time() Components

proc.time() returns a named numeric vector with three elements:

  • user.self — user CPU time for the R process
  • sys.self — system CPU time for the R process
  • elapsed — wall-clock time since R started

The difference between two proc.time() calls gives meaningful timing deltas.

pt <- proc.time()
cat('Names:', names(pt), '
')
cat('Values:', pt, '
')
cat('Class:', class(pt), '
')

Sys.time() for Wall Clock Timestamps

Sys.time() returns the current date and time as a POSIXct object. Unlike proc.time(), it gives you a real-world timestamp, not just CPU usage.

This is useful for logging when something happened, not just how long it took.

start_time <- Sys.time()
cat('Start:', format(start_time), '
')
Sys.sleep(0.05)
end_time <- Sys.time()
cat('End  :', format(end_time), '
')

difftime() to Measure Intervals

difftime(end, start, units='secs') computes the difference between two POSIXct timestamps. You can choose units: 'secs', 'mins', 'hours', 'days'.

This pairs naturally with Sys.time() for readable timing output.

t1 <- Sys.time()
x <- cumsum(1:500000)
t2 <- Sys.time()
delta <- difftime(t2, t1, units = 'secs')
cat('Time taken:', round(as.numeric(delta), 4), 'seconds
')

Timing in a Loop with replicate()

A single timing measurement can vary due to garbage collection or OS scheduling. replicate(n, system.time(expr)['elapsed']) runs the expression multiple times and returns a vector of elapsed times.

Taking the median of replicated timings gives a more stable estimate.

times <- replicate(10, system.time({
  x <- rnorm(10000)
  mean(x)
})['elapsed'])
cat('Median elapsed:', median(times), 'seconds
')
cat('Range:', range(times), '
')

Comparing Two Approaches

Use system.time() to directly compare two implementations of the same task. This pattern helps you confirm that one approach is faster before committing to it.

n <- 100000
t_loop <- system.time({
  result <- numeric(n)
  for (i in seq_len(n)) result[i] <- i^2
})['elapsed']

t_vec <- system.time({
  result <- seq_len(n)^2
})['elapsed']

cat('Loop   :', t_loop, 's
')
cat('Vector :', t_vec, 's
')
cat('Speedup:', round(t_loop / max(t_vec, 1e-6), 1), 'x
')

Timing Nested Operations

You can nest system.time() calls or use proc.time() checkpoints inside a workflow to identify which step is the bottleneck.

Print intermediate deltas as the script runs to build a timeline of your pipeline.

p0 <- proc.time()
x <- rnorm(200000)
p1 <- proc.time()
y <- sort(x)
p2 <- proc.time()
z <- cumsum(y)
p3 <- proc.time()

cat('Generate:', (p1-p0)['elapsed'], 's
')
cat('Sort    :', (p2-p1)['elapsed'], 's
')
cat('Cumsum  :', (p3-p2)['elapsed'], 's
')

Practical Tips for Timing

Keep these practices in mind when timing R code:

  • Run the code once before timing to warm up the JIT and file caches
  • Use gc() before timing to reset garbage collection state
  • Prefer median over mean across replications — outliers from GC skew mean
  • Time the bottleneck, not the whole script
gc()  # clear garbage before timing
times <- replicate(5, system.time({
  m <- matrix(rnorm(1000 * 1000), nrow = 1000)
  crossprod(m)
})['elapsed'])
cat('Median:', median(times), 's
')

Quick Check: system.time() Components

Which component of system.time() represents the actual wall-clock seconds that passed during execution?

Performance Timing Recap

You now have three complementary timing tools in base R:

  • system.time(expr) — quickest way to time one expression; returns user/sys/elapsed
  • proc.time() — snapshot-based timing for arbitrary code blocks
  • Sys.time() + difftime() — wall-clock timestamps and human-readable intervals

Use replicate() to get stable median timings before drawing conclusions about performance.

Free to start

Learn R with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
43
Lessons
159

Frequently Asked Questions

Is the “system.time() and proc.time()” lesson free?

Yes — any 3 lessons of the R Academy learning path, including “system.time() and proc.time()”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The R Academy course includes 4 lessons in total.

What will I learn in “system.time() and proc.time()”?

Measure elapsed, user, and system time for R expressions. You practise R Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start R Academy?

No prior experience is required. R Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 1 of 4.

How long does the “system.time() and proc.time()” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this R Academy lesson?

Yes. Every R Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. system.time() and proc.time()
  2. Profiling Code with Rprof and profvis
  3. Vectorization for Speed
  4. Benchmarking with microbenchmark
← Back to R Academy