未来调用者与库的延迟

问题描述 投票:0回答:1

我正在使用 future Promise 与管道工包中的 API 进行交互。为了避免 RAM 积累,我使用了 callr plan(查看this post 了解更多详情),但它会在每个 API 的计算中产生延迟(将某些 API 从 0.1 秒缩短到 3 秒,这会严重影响性能),我正在寻找减少这种延迟的方法。

当我从下面的 reprex 运行 API1 时,多会话计划需要 0.2 秒,调用者需要 3.1 秒。在这两种情况下,计算 Promise 的时间都非常短(0.01 秒,通过 API 内的 Sys.time 进行测量)。因此我得出的结论是延迟来自于承诺准备。

延迟似乎与承诺中使用的 R 包有关。我比较了3个API:API1使用之前加载的terra包。 API2 使用带有

terra::rast
的 terra 包。 API3不使用terra,但有一个
Sys.sleep()
对应于我正在使用的terra函数的计算时间。 API1 和 API2 都需要 3 秒来计算,但承诺时间有所不同(API1 在 0.01 秒内计算出承诺,API2 需要 2.4 秒)。 API3 速度更快,计算时间为 0.7 秒(包括承诺的 0.03 秒)。因此,延迟似乎来自于处理包(我有类似 sf 包的东西),并且之前加载包(
library(terra)
)或调用它们进行特定用途(
terra::rast()
)并没有什么区别。有没有办法减少这种延迟?

以下是代表:

调用 API 的脚本(您可以选择注释 L3 或 L4 以使用多会话或调用者进行测试):

### Set the asynchronous coding
library(promises) ; library(future) ; library(future.callr)
#future::plan("multisession")
future::plan(future.callr::callr)

### Plumber app
library(plumber)

### Other libraries
library(terra)

### Measure time to compute the terra function
T1_delay=Sys.time() ; terra_delay=terra::rast(xmin=-10, xmax=10, ymin=-10, ymax=10, resolution=10, crs="+init=epsg:4326") ; Delay=Sys.time()-T1_delay

### Start app 
pr <- pr("Test_callr_APIs.R")
pr %>% pr_run()

保存在“Test_callr_APIs.R”中的代码:

#* API1
#* @get species/<scientific_name>/API1
#* @param scientific_name:string Scientific Name
#* @serializer unboxedJSON
#* @tag test
function(scientific_name) {
  
  Prom<-future({
    T1<-Sys.time()
    
    raster_test<-rast(xmin=-10, xmax=10, ymin=-10, ymax=10, resolution=10, crs="+init=epsg:4326")

    cat(Sys.time()-T1, "\n")
    return(list(object_to_return=2))
    
  }, gc=T, seed=T)
  
  return(Prom)
  
}


#* API2
#* @get species/<scientific_name>/API2
#* @param scientific_name:string Scientific Name
#* @serializer unboxedJSON
#* @tag test
function(scientific_name) {
  
  Prom<-future({
    T1<-Sys.time()
    
    raster_test<-terra::rast(xmin=-10, xmax=10, ymin=-10, ymax=10, resolution=10, crs="+init=epsg:4326")
    
    cat(Sys.time()-T1, "\n")
    return(list(object_to_return=2))
    
  }, gc=T, seed=T)
  
  return(Prom)
  
}


#* API3
#* @get species/<scientific_name>/API3
#* @param scientific_name:string Scientific Name
#* @serializer unboxedJSON
#* @tag test
function(scientific_name) {
  
  Prom<-future({
    T1<-Sys.time()
    
    Sys.sleep(Delay)  
    
    cat(Sys.time()-T1, "\n")
    return(list(object_to_return=2))
    
  }, gc=T, seed=T)
  
  return(Prom)
  
}
r asynchronous plumber r-future
1个回答
0
投票

您观察到的延迟增加来自于

future.callr::callr
每次启动新的 R 进程(使用
callr::r_bg()
)以及在该新进程中加载所有必需的包。这需要时间,而且没有太多可做的。我唯一能想象的就是看看
callr::r_bg()
是否可以变得更快(我对此表示怀疑)以及R和
Rscript
本身的启动过程(R-devel邮件列表的东西)。

© www.soinside.com 2019 - 2024. All rights reserved.