R很长矢量的查找时间

时间:2016-06-22 16:06:40

标签: r indexing lookup

用R编程语言......

我的代码中的瓶颈:

a  <-  a[b]

其中:

  • ab是长度为9000万的向量。
  • a是一个逻辑向量。
  • ba
  • 的排列的排列

此操作很慢:需要约1.5 - 2.0秒。

我认为即使对于大型向量,直接索引也会快得多。

我只是卡住了吗?或者有办法加快速度吗?

上下文

P是一个大矩阵(10k行,5k列)。

rows = names,columns = features。值=实数。

问题:给定一个名称子集,我需要获取矩阵Q,其中:

  • 对Q的每一列进行排序(独立于Q的其他列)。
  • Q列中的值来自P的相应列,并且只是来自给定名称子集中P行的那些值。

这是一个天真的实现:

Psub  <-  P[names,]
Q  <-  sapply( Psub , sort )

但我获得了10,000个不同的名称子集(每个子集占总数的20%到90%)。每次进行子集和排序都非常慢。

相反,我可以预先计算订单向量:

b  <-  sapply( P , order )

b  <-  convert_to_linear_index( as.data.frame(b) , dim(P) )
# my own function. 
# Now b is a vector of length  nrow(P) * ncol(P)

a  <-  rownames(P)  %in%  myNames
a  <-  rep(a , ncol(P) )

a  <-  a[b]

a  <-  as.matrix(a , nrow = length(myNames) )

1 个答案:

答案 0 :(得分:3)

我不认为这比这快得多。您可以尝试编写一个优化的C函数来完成这一操作,这可能会将时间缩短一半左右(而且乐观 - 像这样的矢量化R操作没有太多开销),但不会多于此。< / p>

你有大约10 ^ 8个值要经过。每次通过内部循环时,它需要递增迭代器,从内存中获取索引b[i],查找a[b[i]]然后将该值保存到newa[i]。我不是一个远程编译器/汇编专家,但这听起来像5-10条指令的顺序,这意味着你正在查看总共10亿条指令的“大O”,所以有一个时钟速率限制这有多快。

此外,R将逻辑值存储为32位整数,因此数组a将占用大约400兆位,这不适合缓存,因此如果b或多或少是随机的排列,那么你将定期错过缓存(事实上,大多数查找到a)。同样,我不是专家,但我认为这里的缓存未命中可能是瓶颈,如果是这样的话,优化后的C将无济于事。

除了在C中编写它之外,另一件事是确定是否有任何假设可以让你不通过整个数组。例如,如果您知道大多数索引不会改变,并且您可以确定哪些索引发生了变化,那么您可以使其更快。

编辑时,这里有一些数字。我的AMD时钟速度为2.8GHz。随机排列(即大量缓存未命中)需要3.4秒,1:nn:1需要0.7秒(即缓存未命中极少),这会导致0.6秒的执行时间和0.1系统时间,大概是分配新阵列。所以看起来确实存在缓存未命中。也许优化的C代码可以削减基本时间的0.2或0.3秒,但如果排列是随机的,那将没有太大的区别。

> x<-sample(c(T,F),90*10**6,T)
> prm<-sample(90*10**6)
> prm1<-1:length(prm)
> prm2<-rev(prm1)
> system.time(x<-x[prm])
   user  system elapsed 
  3.317   0.116   3.436 
> system.time(x<-x[prm1])
   user  system elapsed 
  0.593   0.140   0.734 
> system.time(x<-x[prm2])
   user  system elapsed 
  0.631   0.112   0.743 
>