在某一点之后,我的R程序突然变慢了。 为什么?

我教自己R.程序的细节可能并不重要,但它构造了一组节点(每个都有8个参数,所有整数)和边(每个都有4个整数参数)。 最初,我尝试将这些列表存储为列表。 但是,当我试图构建一个非常大的节点集时,程序顺利进行,直到有大约30,000个节点和64,000个边,然后非常突然地变慢。

我认为这个问题可能以某种方式涉及可用内存(尽管这些列表分别占用了19.3MB和39.5MB)。 我将分页文件大小从8097增加到12145 MB,并在12145处设置了memory.limit,但没有任何效果。 我还尝试将数据存储在不同的结构中:整数矩阵,data.frame和big.matrix(来自包“bigmemory”)。 无论数据结构如何,该程序都会在同一时刻慢慢爬行。 它不会完全停止 - 它只会减慢一到两个数量级。

能否有比我更有经验的人简要解释为什么这样的减速会发生? 是否有多个可能的原因需要我研究? 特别是,我对速度的突然变化感到困惑。 代码似乎以恒定的速度运行,直到它碰到我上面描述的“墙”。

我已经通过Stackoverflow上的其他几篇帖子梳理了人们抱怨程序变慢的问题,但这些似乎都涉及内存问题,我认为这是我排除的问题。

我已经发布了下面的代码,但它很漫长而且令人费解,对于任何人来说都可能太漫长了。 这里有一些可能的重要事实:

  • 该算法是O(n),或几乎如此。
  • 没有实际的递归。 程序的核心是一个while循环,它调用五个函数之一; 该函数返回需要被调用的函数的标识,然后while循环调用该函数。
  • 五个功能中的每一个都可以:添加一个或两个边或节点; 改变一个或两个边或节点的参数; 和/或改变一些控制该算法的全局参数。
  • 这是代码本身,以防细节很重要。 这是big.matrix版本,但所有其他版本具有相同的基本结构。 这是Ukkonen构建后缀树算法的奇怪实现。 我很抱歉发布如此长的一段代码。

    library(bigmemory)
    
    
    clear <- function (){
      n <<- big.matrix(150000,8, type = "integer", init = 0L)
      colnames(n) <<- c("A", "C", "G", "T", "$", "root", "link", "distance")
      e <<- big.matrix(200000,4, type = "integer", init = 0L)
      colnames(e) <<- c("from","to","start","stop")
    }
    
    AT_NODE <- function(){
      temp1 <- n[a_node, u(curr_idx)]
      if (temp1==0){
        return (INSERT_BRANCH)
      }
      temp2 <- e[temp1,"stop"] - e[temp1,"start"] + 1L
      if (min_dist >= temp2){
        if (length(e[temp1,"to"]) == 0){
          a_node <<- 1L
          curr_idx <<- curr_suffix <<- curr_suffix + 1L
          return (AT_NODE)
        } else {
        min_dist <<- min_dist - temp2
        curr_idx <<- curr_idx + temp2
        a_node <<- e[temp1,"to"]
        return (AT_NODE)
        }
      } else {
        a_pos <<- a_pos + min_dist
        curr_idx <<- curr_idx + min_dist
        a_edge <<- temp1
        return (STEP_FORWARD)
      }
    }
    
    INSERT_BRANCH <- function(){
      e[e_ptr+1,] <<- c(a_node, 0L, curr_idx, as.integer(nchar(strg)))
      e_ptr <<- e_ptr+1L
      n[a_node, u(curr_idx)] <<- e_ptr
      return (SUFFIX_JUMP)
    }
    
    STEP_FORWARD <- function(){
      if (u(curr_idx) == u(e[a_edge,"start"] + a_pos - 1L)){
       a_pos <<- a_pos + 1L
        curr_idx <<- curr_idx + 1L
        if (a_pos > (e[a_edge,"stop"] - e[a_edge,"start"] + 1L)){
          a_pos <<- 1L
          if (curr_idx > nchar(strg)){
            a_node <<- 1L
            curr_idx <<- curr_suffix <<- curr_suffix + 1L
            return (AT_NODE)
          } else {
            a_node <<- e[a_edge,"to"]
            min_dist <<- max (0L, (min_dist - (e[a_edge,"stop"] - e[a_edge,"start"] + 1L)))
            return (AT_NODE)
          }
        } else {
          return (STEP_FORWARD)
        }
      } else {
        return (ADD_NODE)
      }
    }
    
    ADD_NODE <- function(){
      min_dist <<- n[e[a_edge,"from"],"distance"] + a_pos - 1L
      n_ptr <<- n_ptr + 1L
      n[n_ptr,u(curr_idx)] <<- e_ptr + 1L
      n[n_ptr,u(e[a_edge, "start"] + a_pos - 1L)] <<- e_ptr + 2L
      n[n_ptr, "root"] <<- a_edge
      n[n_ptr, "distance"] <<- min_dist
      e[e_ptr + 1L,] <<- c(n_ptr, 0L, curr_idx, as.integer(nchar(strg)))
      e[e_ptr + 2L,] <<- c(n_ptr, e[a_edge,"to"], e[a_edge, "start"] + a_pos - 1L, e[a_edge,"stop"])
      e[a_edge,"to"] <<- n_ptr
      e[a_edge,"stop"] <<- e[a_edge,"start"] + a_pos - 2L
      e_ptr <<- e_ptr + 2L
    
      if (a_node == 1){
        min_dist <<- max(0L, min_dist - 1L)
      }
      min_dist <<- max(0L, min(min_dist, (curr_idx - curr_suffix - n[a_node,"distance"])))
      a_node <<- n_ptr
      if (e[n[a_node,"root"],"from"] == 1 & (e[n[a_node,"root"],"stop"] - e[n[a_node,"root"],"start"]) == 0){
        n[a_node,"link"] <<- 1L
        suffix_link <<- 0L
      }
      return (SUFFIX_JUMP)
    }
    
    SUFFIX_JUMP <- function(){
      if (suffix_link != 0L){
        n[suffix_link,"link"] <<- a_node
      }
      if (a_node > 1){
        suffix_link <<- a_node
      }
      a_pos <<- 1L
      curr_idx <<- curr_suffix <<- curr_suffix + 1L
      temp1 <- n[orig_node,"link"]
      if (temp1 > 1){
        a_node <<- orig_node <<- temp1
        curr_idx <<- curr_idx + n[a_node,"distance"]
        return (AT_NODE)
      }
      min_dist <<- max(0L, min_dist -1L)
      orig_node <<- a_node <<- 1L
      #print ("headed to root")
      return (AT_NODE)
    }
    
    Ukkonen <- function (strg){
      strg <<- paste0(c(strg, "$"), collapse = "")
      action <- AT_NODE
    
      while (curr_suffix < (nchar(strg)+2)){
        temp1 <- do.call(action, list())
        action <- temp1
      }
    }
    
    strg <- <<a string of 89,000 nucleotides>>
    a_edge <- min_dist <- suffix_link <- e_ptr <- 0L
    curr_suffix <- curr_idx <- a_pos <- a_node <- n_ptr <- orig_node <- 1L
    clear()
    Ukkonen(strg)
    
    链接地址: http://www.djcxy.com/p/31867.html

    上一篇: After a certain point, my R program suddenly slows to a crawl. Why?

    下一篇: Handle large data sets calculating SPI in R