用R编程语言......
我的代码中的瓶颈:
a <- a[b]
其中:
a
,b
是长度为9000万的向量。 a
是一个逻辑向量。b
是a
。此操作很慢:需要约1.5 - 2.0秒。
我认为即使对于大型向量,直接索引也会快得多。
我只是卡住了吗?或者有办法加快速度吗?
上下文
P是一个大矩阵(10k行,5k列)。
rows = names,columns = features。值=实数。
问题:给定一个名称子集,我需要获取矩阵Q,其中:
这是一个天真的实现:
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) )
答案 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:n
或n: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
>