在某一点之后,我的R程序突然变慢了。 为什么?
我教自己R.程序的细节可能并不重要,但它构造了一组节点(每个都有8个参数,所有整数)和边(每个都有4个整数参数)。 最初,我尝试将这些列表存储为列表。 但是,当我试图构建一个非常大的节点集时,程序顺利进行,直到有大约30,000个节点和64,000个边,然后非常突然地变慢。
我认为这个问题可能以某种方式涉及可用内存(尽管这些列表分别占用了19.3MB和39.5MB)。 我将分页文件大小从8097增加到12145 MB,并在12145处设置了memory.limit,但没有任何效果。 我还尝试将数据存储在不同的结构中:整数矩阵,data.frame和big.matrix(来自包“bigmemory”)。 无论数据结构如何,该程序都会在同一时刻慢慢爬行。 它不会完全停止 - 它只会减慢一到两个数量级。
能否有比我更有经验的人简要解释为什么这样的减速会发生? 是否有多个可能的原因需要我研究? 特别是,我对速度的突然变化感到困惑。 代码似乎以恒定的速度运行,直到它碰到我上面描述的“墙”。
我已经通过Stackoverflow上的其他几篇帖子梳理了人们抱怨程序变慢的问题,但这些似乎都涉及内存问题,我认为这是我排除的问题。
我已经发布了下面的代码,但它很漫长而且令人费解,对于任何人来说都可能太漫长了。 这里有一些可能的重要事实:
这是代码本身,以防细节很重要。 这是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?