使用内联函数定义将列表元素与 lapply 相乘的速度几乎是使用标准“*”的两倍
Multiplying elements of list with lapply is almost twice as fast with in-line function definition than with standard "*"
如果我们想用一个常数乘以一个列表的元素,我们可以用lapply来实现。但是,我观察到定义要在线应用的函数比指定“*”作为要应用的函数快几乎两倍:
library(microbenchmark)
microbenchmark::microbenchmark(x=lapply(X=list(a=c(1,2,3)), FUN=function(x) x*1000), y=lapply(X=list(a=c(1,2,3)), "*", 1000), times = 10000)
第一个表达式的中值约为 1100 纳秒,第二个表达式的中值约为 1900 纳秒。
知道为什么会发生这种情况吗?
lapply
调用 match.fun
,它必须花费一些时间(嗯,大约一微秒)将字符串 "*"
与原始函数 `*`
匹配。直接传递函数可以避免开销。
l <- list(1, 2, 3)
microbenchmark::microbenchmark(lapply(l, function(x) x * 1000),
lapply(l, "*", 1000),
lapply(l, `*`, 1000),
times = 1e+06L)
## Unit: nanoseconds
## expr min lq mean median uq max neval
## lapply(l, function(x) x * 1000) 1271 1435 1614.497 1476 1517 1243981 1e+06
## lapply(l, "*", 1000) 1640 1763 2026.791 1804 1886 16498605 1e+06
## lapply(l, `*`, 1000) 861 984 1198.956 1025 1066 16636365 1e+06
microbenchmark::microbenchmark(match.fun(function(x) x * 1000),
match.fun("*"),
match.fun(`*`),
times = 1e+06L)
## Unit: nanoseconds
## expr min lq mean median uq max neval
## match.fun(function(x) x * 1000) 82 164 249.0617 205 205 15783606 1e+06
## match.fun("*") 779 902 1036.1593 902 984 15515261 1e+06
## match.fun(`*`) 41 164 187.4243 164 164 588842 1e+06
也就是说,match.fun
永远不会成为瓶颈,除非您可能编写了一个调用 match.fun
数十亿次的函数,因此在此级别进行优化只是“为了好玩"。
如果我们想用一个常数乘以一个列表的元素,我们可以用lapply来实现。但是,我观察到定义要在线应用的函数比指定“*”作为要应用的函数快几乎两倍:
library(microbenchmark)
microbenchmark::microbenchmark(x=lapply(X=list(a=c(1,2,3)), FUN=function(x) x*1000), y=lapply(X=list(a=c(1,2,3)), "*", 1000), times = 10000)
第一个表达式的中值约为 1100 纳秒,第二个表达式的中值约为 1900 纳秒。
知道为什么会发生这种情况吗?
lapply
调用 match.fun
,它必须花费一些时间(嗯,大约一微秒)将字符串 "*"
与原始函数 `*`
匹配。直接传递函数可以避免开销。
l <- list(1, 2, 3)
microbenchmark::microbenchmark(lapply(l, function(x) x * 1000),
lapply(l, "*", 1000),
lapply(l, `*`, 1000),
times = 1e+06L)
## Unit: nanoseconds
## expr min lq mean median uq max neval
## lapply(l, function(x) x * 1000) 1271 1435 1614.497 1476 1517 1243981 1e+06
## lapply(l, "*", 1000) 1640 1763 2026.791 1804 1886 16498605 1e+06
## lapply(l, `*`, 1000) 861 984 1198.956 1025 1066 16636365 1e+06
microbenchmark::microbenchmark(match.fun(function(x) x * 1000),
match.fun("*"),
match.fun(`*`),
times = 1e+06L)
## Unit: nanoseconds
## expr min lq mean median uq max neval
## match.fun(function(x) x * 1000) 82 164 249.0617 205 205 15783606 1e+06
## match.fun("*") 779 902 1036.1593 902 984 15515261 1e+06
## match.fun(`*`) 41 164 187.4243 164 164 588842 1e+06
也就是说,match.fun
永远不会成为瓶颈,除非您可能编写了一个调用 match.fun
数十亿次的函数,因此在此级别进行优化只是“为了好玩"。