0Pricing
R Academy · レッスン

system.time() と proc.time()

R の式にかかった経過時間、ユーザー時間、システム時間を計測します。

「system.time() と proc.time()」はCoddyKit上の無料R Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはR Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 R Academyコースには全4レッスンが含まれています。

パフォーマンスを測定する理由

コードを最適化する前に、まず測定する必要があります。どこが遅いのかを推測すると、無駄な作業につながります。Rには、式の実行時間を正確に測定する組み込みツールがあります。

主なツールはsystem.time()、proc.time()、Sys.time()の3つです。それぞれパフォーマンス分析における役割が異なります。

system.time()の基本

system.time(expr)は式を評価し、かかった時間を返します。Rで1つの処理の実行時間を測定する最も簡単な方法です。

結果はproc_timeクラスのオブジェクトで、名前付きの要素を調べられます。

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

3つの時間の値を読み取る

system.time()は5つの値を返しますが、特に重要なのは次の3つです:

  • user — Rのコード自体が使用したCPU時間
  • sys — Rに代わってオペレーティングシステムが使用したCPU時間
  • elapsed — 実時間(経過した実際の秒数)

通常、注目すべきなのはelapsedです。マルチコアのマシンでは、user + sysがelapsedを上回ることがあります。

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

手動での時間測定にproc.time()を使う

proc.time()は、現在のCPU時間と経過時間をスナップショットとして返します。コードブロックの前後で取得すれば、任意のコード部分の実行時間を測定できます。

終了時のスナップショットから開始時のスナップショットを引くと、その部分の経過時間が得られます。

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

proc.time()の構成要素

proc.time()は、次の3つの要素を持つ名前付き数値ベクトルを返します:

  • user.self — RプロセスのユーザーCPU時間
  • sys.self — RプロセスのシステムCPU時間
  • elapsed — Rの起動以降の実時間

2回のproc.time()呼び出しの差分から、意味のある時間差を求められます。

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

実時間のタイムスタンプにSys.time()を使う

Sys.time()は現在の日付と時刻をPOSIXctオブジェクトとして返します。proc.time()とは異なり、CPU使用量ではなく、現実世界のタイムスタンプを取得できます。

これは、どれだけ時間がかかったかではなく、いつ何が起きたかをログに記録する場合に便利です。

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

間隔の測定にdifftime()を使う

difftime(end, start, units='secs')は、2つのPOSIXctタイムスタンプの差を計算します。単位には'secs'、'mins'、'hours'、'days'を指定できます。

Sys.time()と組み合わせると、読みやすい時間測定結果を自然に出力できます。

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
')

replicate()を使ったループ内の時間測定

ガベージコレクションやOSのスケジューリングによって、1回の測定結果は変動することがあります。replicate(n, system.time(expr)['elapsed'])は式を複数回実行し、経過時間のベクトルを返します。

繰り返し測定した時間の中央値を取ると、より安定した推定値が得られます。

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

2つの方法を比較する

同じタスクに対する2つの実装を直接比較するには、system.time()を使います。このパターンを使うと、ある方法を採用する前に、それがより高速であることを確認できます。

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
')

ネストされた処理の時間を測定する

system.time()の呼び出しをネストしたり、ワークフロー内にproc.time()のチェックポイントを設けたりすると、ボトルネックとなっている手順を特定できます。

スクリプトの実行中に中間の差分を出力すると、パイプラインのタイムラインを作成できます。

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
')

時間測定の実践的なヒント

Rコードの実行時間を測定するときは、次の点を意識してください:

  • 測定前にコードを1回実行し、JITとファイルキャッシュをウォームアップします
  • 測定前にgc()を使い、ガベージコレクションの状態をリセットします
  • 繰り返し測定では平均値より中央値を優先します — GCによる外れ値が平均値を偏らせるためです
  • スクリプト全体ではなく、ボトルネックの時間を測定します
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
')

クイックチェック:system.time()の構成要素

system.time()のどの構成要素が、実行中に経過した実際の秒数を表しますか?

パフォーマンス測定のまとめ

base Rには、目的の異なる次の3つの時間測定ツールがあります:

  • system.time(expr) — 1つの式を測定する最も簡単な方法で、user/sys/elapsedを返します
  • proc.time() — 任意のコードブロックをスナップショット方式で測定します
  • Sys.time() + difftime() — 実時間のタイムスタンプと、人が読みやすい時間間隔を取得します

パフォーマンスについて結論を出す前に、replicate()を使って安定した中央値の測定値を取得してください。

よくある質問

「system.time() と proc.time()」レッスンは無料ですか?

はい。「system.time() と proc.time()」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、R Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 R Academyコースには全4レッスンが含まれています。

「system.time() と proc.time()」で何を学びますか?

R の式にかかった経過時間、ユーザー時間、システム時間を計測します。 ブラウザで直接実行するハンズオンコードでR Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

R Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのR Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「system.time() と proc.time()」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このR Academyレッスンでコードを書いて実行できますか?

はい。すべてのR Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. system.time() と proc.time()
  2. Rprof と profvis でコードをプロファイリングする
  3. 高速化のためのベクトル化
  4. microbenchmark でベンチマークを行う
← R Academyに戻る