observeEvent()会比isolate()有更好的性能吗?

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

我对isolate()和observeEvent()的用法感到困惑。如下所示的代码,这两个代码似乎执行相同的工作 - 仅在单击按钮后渲染绘图。 但是,当我在部署在shinyapps.io 上的应用程序中使用isolate() 函数时,我的应用程序由于内存使用量过多而崩溃。 (我在这里简化了图形代码只是为了演示。实际的代码要复杂得多。)我想知道isolate()是否对这个错误做了任何事情。用observeEvent()替换isolate()函数是否有助于提高性能?

library(shiny)
library(stats)

runApp(list(
  ui = bootstrapPage(
    textInput(inputId = "text_in",
              label = "Type something:"),
    actionButton(inputId = "submit",
                 label = "submit"),
    plotOutput(outputId = "testpic")
  ),
  server = function(input, output) {
    output$testpic <- renderPlot({
      if (input$submit == FALSE) return()
      isolate({
        x  <- as.matrix(mtcars)
        rc <- rainbow(nrow(x), start = 0, end = .3)
        cc <- rainbow(ncol(x), start = 0, end = .3)
        heatmap(x, col = cm.colors(256), scale = "column",
                RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
                xlab = input$text_in, ylab =  input$text_in,
                main = input$text_in)
      })
    })
  }
))
library(shiny)
library(stats)

runApp(list(
  ui = bootstrapPage(
    textInput(inputId = "text_in",
              label = "Type something:"),
    actionButton(inputId = "submit",
                 label = "submit"),
    plotOutput(outputId = "testpic")
  ),
  server = function(input, output) {
    vplot <- eventReactive(input$submit, {
      x  <- as.matrix(mtcars)
      rc <- rainbow(nrow(x), start = 0, end = .3)
      cc <- rainbow(ncol(x), start = 0, end = .3)
      heatmap(x, col = cm.colors(256), scale = "column",
              RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
              xlab = input$text_in, ylab =  input$text_in,
              main = input$text_in)
    })
    
    observeEvent(input$submit, {
      output$testpic <- renderPlot({vplot()})
    })
  }
))

我使用profvis()来比较它们的性能差异。事实证明,也许isolate()比observeEvent做得更好,这相当令人震惊,并且违背了我之前的知识。

r shiny shiny-reactivity
1个回答
0
投票

output
槽封闭在观察者内部是不好的做法。我认为这就是为什么
profvis
报告表现最差。

我看到服务器的三种可能性:

library(shiny)

ui <- bootstrapPage(
  textInput(inputId = "text_in", label = "Type something:"),
  actionButton(inputId = "submit", label = "submit"),
  plotOutput(outputId = "testpic")
)

server1 <- function(input, output) {
  
  output$testpic <- renderPlot({
    req(input$submit)
    isolate({
      x  <- as.matrix(mtcars)
      rc <- rainbow(nrow(x), start = 0, end = .3)
      cc <- rainbow(ncol(x), start = 0, end = .3)
      heatmap(x, col = cm.colors(256), scale = "column",
              RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
              xlab = input$text_in, ylab =  input$text_in,
              main = input$text_in)
    })
  })
  
}

server2 <- function(input, output) {
  
  Heatmap <- eventReactive(input$submit, {
    x  <- as.matrix(mtcars)
    rc <- rainbow(nrow(x), start = 0, end = .3)
    cc <- rainbow(ncol(x), start = 0, end = .3)
    heatmap(x, col = cm.colors(256), scale = "column",
            RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
            xlab = input$text_in, ylab =  input$text_in,
            main = input$text_in)
  })
  
  output$testpic <- renderPlot({
    Heatmap()
  })
  
}

server3 <- function(input, output) {
  
  output$testpic <- renderPlot({
    x  <- as.matrix(mtcars)
    rc <- rainbow(nrow(x), start = 0, end = .3)
    cc <- rainbow(ncol(x), start = 0, end = .3)
    heatmap(x, col = cm.colors(256), scale = "column",
            RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
            xlab = input$text_in, ylab =  input$text_in,
            main = input$text_in)
  }) |> bindEvent(input$submit)
  
}

然后你可以运行:

profvis::profvis({
  app <- shinyApp(ui, server1)
  runApp(app)
})
profvis::profvis({
  app <- shinyApp(ui, server2)
  runApp(app)
})
profvis::profvis({
  app <- shinyApp(ui, server3)
  runApp(app)
})

我尝试过,结论是

server3
在记忆方面是最好的,而
server1
,使用
isolate
,是最差的。

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