You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何purrr::map2相比base::mapply运行速度慢近8倍?

Why purrr::map2 is slower than base::mapply (and how to optimize it)

First, let's confirm your benchmark results with properly formatted code:

library(purrr)
library(microbenchmark)

list1 <- as.list(rep(1, 50))
list2 <- as.list(rep(1, 50))

# Benchmark purrr::map2
microbenchmark::microbenchmark(
  map2(list1, list2, sum)
)
# Unit: microseconds
# expr                          min    lq      mean   median    uq     max neval
# map2(list1, list2, sum) 375.31 384.2045 481.8708 407.8115 420.641 7923.58   100

# Benchmark base::mapply
microbenchmark::microbenchmark(
  mapply(sum, X=list1, Y=list2, SIMPLIFY = FALSE)
)
# Unit: microseconds
# expr                                                         min     lq      mean   median      uq     max neval
# mapply(sum, X = list1, Y = list2, SIMPLIFY = FALSE) 46.187 50.634 57.45634 53.3715 59.8715 127.27   100

Your observation is spot-on—map2 is roughly 8x slower here. Let's break down why this happens, then cover actionable fixes.

Why map2 has more overhead

  1. Safety checks and abstraction
    purrr functions are built to be user-friendly and robust. map2 automatically verifies your input lists have matching lengths, handles edge cases like empty lists, and ensures consistent output structures. These safety features add fixed overhead that's negligible for large tasks but sticks out like a sore thumb when you're running tiny operations (like summing 50 scalar pairs).

    mapply with SIMPLIFY=FALSE is a leaner, lower-level tool—it skips most of these checks and directly executes loop logic, making it faster for straightforward use cases.

  2. Indirect function wrapping
    map2 wraps your target function (sum here) into a closure that accepts two arguments, adding an extra layer of function call overhead. mapply binds arguments directly to sum without this wrapping, creating a shorter, faster execution path.

  3. Small task amplification
    When you're running a tiny operation (summing two scalars) 50 times, the fixed overhead of map2 (initialization, argument validation) makes up a huge chunk of total runtime. If you tested with larger lists (e.g., 10,000 elements) or more complex functions, the performance gap would shrink dramatically—purrr's overhead becomes less significant relative to the actual work being done.

Optimization strategies

1. Use mapply directly (when appropriate)

If your use case is simple (no need for purrr's pipe compatibility, type-specific outputs, or other purrr features), stick with mapply(sum, list1, list2, SIMPLIFY=FALSE)—it's the fastest option here, as your benchmark shows.

2. Use purrr's type-specific variants

purrr has optimized functions for specific output types that avoid the overhead of returning a generic list. For numeric outputs, try map2_dbl:

microbenchmark::microbenchmark(
  map2_dbl(list1, list2, sum)
)
# You'll see this runs much closer to mapply's speed—often within 2x instead of 8x

map2_dbl skips list creation and directly outputs a numeric vector, cutting down on unnecessary overhead.

3. Vectorize the operation (if possible)

Since your list elements are scalars, you can skip mapping entirely by converting lists to vectors and using R's native vectorized operations:

microbenchmark::microbenchmark(
  unlist(list1) + unlist(list2)
)
# This will be even faster than mapply—vector operations are R's sweet spot

This eliminates loop overhead entirely and is the most efficient approach for scalar list pairs.

If you're absolutely sure your inputs are consistent (matching lengths, no edge cases), you can use purrr's unexported map2_raw function, which skips most validation:

microbenchmark::microbenchmark(
  purrr:::map2_raw(list1, list2, sum)
)

Note: This is an internal function, so it could break in future purrr updates—use this only for temporary, performance-critical code.

内容的提问来源于stack exchange,提问作者ℕʘʘḆḽḘ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:22:38