向量化程式碼的重要性

撰寫高效 R 程式碼

Colin Gillespie

Jumping Rivers & Newcastle University

通用原則

  • 呼叫 R 函式最終會執行 C 或 FORTRAN 程式碼
    • 這些程式碼已被高度最佳化

目標

  • 盡快進入底層的 C 或 FORTRAN 程式碼;呼叫越少層函式越好。
撰寫高效 R 程式碼

向量化函式

  • 許多 R 函式是向量化的
    • 輸入單一數字,回傳向量
rnorm(4)
-0.7247  0.2502  0.3510  0.6919
  • 向量作為輸入
mean(c(36, 48))
42
撰寫高效 R 程式碼

產生亂數

library(microbenchmark)
n <- 1e6
x <- vector("numeric", n)
microbenchmark(
    x <- rnorm(n),
    {
        for(i in seq_along(x))
            x[i] <- rnorm(1)
        },
    times = 10
)
# Unit: milliseconds
# expr        lq mean    uq  cld
# rnorm(n)    60   70    80  a
# Looping   2600 2700  2800   b

## Output trimmed for presentation

比較

x <- vector("numeric", n)
for(i in seq_along(x))
    x[i] <- rnorm(1)

x <- rnorm(n)
撰寫高效 R 程式碼

為什麼迴圈很慢?

迴圈
x <- vector("numeric", n)
for(i in seq_along(x))
    x[i] <- rnorm(1)
配置
x <- vector("numeric", n)
  • _迴圈_:一次性成本
  • 向量化:相當
產生
  • _迴圈_:呼叫 rnorm() 一百萬次
  • 向量化:只呼叫 rnorm() 一次
指派
  • _迴圈_:呼叫指定方法一百萬次
  • 向量化:只指定一次
撰寫高效 R 程式碼

R 俱樂部

R 俱樂部第二條:只要可行,就用向量化解法。

撰寫高效 R 程式碼

一起來練習吧!

撰寫高效 R 程式碼

Preparing Video For Download...