是否可以监控正在使用或已被R用来调用函数的内存量?例如,我有一个任意函数,例如:
smallest.sv <- function(){
A <- matrix(rnorm(1e6), 1e3);
mysvd <- svd(A);
return(tail(mysvd$d, 1));
}
运行该函数只返回一个标量,但是使用了大量内存来计算函数。现在我需要进行性能基准测试。处理时间很简单:
system.time(x <- smallest.sv())
但是我还想知道这个调用需要多少内存,而不需要修改函数(它应该适用于任意函数)。有没有办法做到这一点?
编辑:澄清一下。我最感兴趣的是在函数调用期间使用的内存上限,即需要多少物理内存才能处理函数调用。在许多情况下,这远远低于我认为的分配内存总量。
答案 0 :(得分:20)
R提供内存分析支持,请参阅Section 3.3 of the Writing R Extensions manual:
3.3分析内存使用的R代码
在代码处理时,测量R代码中的内存使用很有用 比方便可用或内存分配更多的内存 并且复制对象是造成代码慢的原因。有三种 在R代码中描述内存使用随时间变化的方法。这三个都要求R到 已经编译了`--enable-memory-profiling',这不是 默认,但目前用于Mac OS X和Windows二进制文件 分布。由于不同的原因,所有这些都可能会产生误导。
在了解内存配置文件时,了解一点是很有用的 更多关于R的内存分配。看看`gc()'的结果 显示了将内存划分为用于存储内容的“Vcells” 向量和'Ncells'用于存储其他所有内容,包括所有内容 类型和长度等向量的管理开销 信息。实际上,矢量内容分为两个池。 获得小向量的存储器(默认为128字节或更少) 大块然后由R包围;更大的向量的记忆是 直接从操作系统获得。
然后再提供三个部分。
答案 1 :(得分:11)
一种选择是使用Rprof
。一个简单的方法是:
Rprof(tf <- "rprof.log", memory.profiling=TRUE)
[your code]
Rprof(NULL)
summaryRprof(tf)
这将为您提供有关内存使用情况的一些信息。
答案 2 :(得分:0)
您可以使用gc
获取在处理函数和命令期间使用的内存上限:
smallest.sv <- function(){
A <- matrix(rnorm(1e6), 1e3);
mysvd <- svd(A);
return(tail(mysvd$d, 1));
}
tt <- sum(.Internal(gc(FALSE, TRUE, TRUE))[13:14])
x <- smallest.sv()
sum(.Internal(gc(FALSE, FALSE, TRUE))[13:14]) - tt
#62 MB
rm(x)
此上限受垃圾收集的影响,因此打开gctorture
将给出最低上限:
tt <- sum(.Internal(gc(FALSE, TRUE, TRUE))[13:14])
gctorture(on = TRUE)
x <- smallest.sv()
gctorture(on = FALSE)
sum(.Internal(gc(FALSE, FALSE, TRUE))[13:14]) - tt
#53.7 MB
诸如Rprof
,Rprofmem
,profmem::profmem
,bench::mark
或profvis::profvis
之类的其他工具也可以显示内存使用情况。
#Using Rprof (Enable profiling is a compile-time option: ./configure --enable_R_profiling)
gc()
Rprof("Rprof.out", memory.profiling=TRUE)
x <- smallest.sv()
Rprof(NULL)
max(summaryRprof("Rprof.out", memory="both")$by.total$mem.total)
#45.9
#Here at defined intervals the status is checked and so the result depends on if you hit the peak
#Using Rprofmem (Enable momory profiling is a compile-time option: ./configure --enable_memory_profiling)
Rprofmem("Rprofmem.out"); x <- smallest.sv(); Rprofmem(NULL) #Wen first run, there is much more in the log file
gc()
Rprofmem("Rprofmem.out")
x <- smallest.sv()
Rprofmem(NULL)
sum(as.numeric(read.table("Rprofmem.out", comment.char = ":")[,1]), na.rm=TRUE)
#88101752
#Writes out them memory amount when it is allocated
library(profmem) #uses utils::Rprofmem
gc()
total(profmem(x <- smallest.sv()))
#88101752
library(bench) #uses utils::Rprofmem
gc()
mark(x <- smallest.sv())[,"mem_alloc"]
#84MB
#Warning message:
#Some expressions had a GC in every iteration; so filtering is disabled.
library(profvis) #uses utils::Rprof
gc()
profvis(x <- smallest.sv())
#opens a browser window where you can read under Memory -23.0 | 45.9
Rprofmem
显示已累积分配的内存,并且不考虑在执行期间释放的内存。要提高Rprof
达到峰值的可能性,您可以选择一个较短的时间间隔或/和/或重复该过程。
max(replicate(10, {
gc()
Rprof("Rprof.out", memory.profiling=TRUE, interval = runif(1,.005,0.02))
x <- smallest.sv()
Rprof(NULL)
max(summaryRprof("Rprof.out", memory="both")$by.total$mem.total)
}))
#76.4
在这里,我得到的值比从gc
中得到的值高,这表明,内存使用量受垃圾回收和函数处理期间使用的内存的上限的影响。 可能因呼叫而异,只要gctorture
未打开即可。
答案 3 :(得分:0)
您可以使用 PeakRAM
获得处理时间和峰值内存:
library(peakRAM)
peakRAM(smallest.sv())
Function_Call Elapsed_Time_sec Total_RAM_Used_MiB Peak_RAM_Used_MiB
1 smallest.sv() 3.64 0 61.1