通过XTS对象和矩阵进行子选择:为什么会有这样的性能损失?

3

在循环相等大小的XTS对象和R矩阵时进行子选择会产生巨大的性能差异。在我的机器上,以下示例中的矩阵代码需要0.42秒,而XTS代码需要31.64秒。假设我必须像这样进行循环,我应该预先使用as.matrix将所有的XTS对象转换为矩阵,还是有一种方法可以从xts对象获得更高的性能?

library(xts)

NumRows <- 1000000
NumCols <- 30
theMatrix <- matrix(rep(1,NumRows*NumCols),nrow=NumRows)
theXTS <- xts(theMatrix,Sys.Date()+1:NumRows)

system.time({  

  for(k in 1:NumRows){
    DataPoint <- theMatrix[k,1]
  }

})

system.time({  

  for(k in 1:NumRows){
    DataPoint <- theXTS[k,1]
  }

})
2个回答

3
是的。简短的回答是,当你对一个xts对象进行子集操作时,你是从向量中提取相关时间,并从矩阵中提取相关行,这比仅从矩阵中提取组件需要更长的计算时间。通常你希望将你的数据保留在xts格式中,以便通过时间轴方便地对数据进行子集操作,但你可以先调用coredata(比as.matrix更快),它会暴露出数据的矩阵,然后通过整数索引对xts对象进行子集操作。
请参阅?coredata
> class(coredata(theXTS))
[1] "matrix"

# Compare benchmark below against subsetting with an existing matrix
theXTS_matrix <- as.matrix(theXTS)

library(microbenchmark)
microbenchmark(theXTS_matrix[5, 7:10], coredata(theXTS), 

coredata(theXTS)[5, 7:10],
                   theXTS[5, 7:10], as.matrix(theXTS)[5, 7:10])
# Unit: nanoseconds
# expr    min       lq      mean   median       uq    max neval
# theXTS_matrix[5, 7:10]    663   1087.5   1479.39   1254.0   1569.0   9062   100
# coredata(theXTS)  10456  12090.5  13413.92  13122.0  14269.0  24106   100
# coredata(theXTS)[5, 7:10]  11703  12959.5  15193.21  14298.5  15499.5  56137   100
# theXTS[5, 7:10]  27519  30293.5  32669.63  31805.5  33130.5  57130   100
# as.matrix(theXTS)[5, 7:10] 200927 205187.5 209949.47 206926.0 212582.0 330426   100

CoreData提供了很小的开销,但子集操作更快。

2
FXQuantTrader的回答提供了几个不错的观点,但他们没有解释这两个函数之间差异的大小。我还要指出,在问题中并没有进行“搜索”:ij已经是整数,所以这只是一个直接的索引操作。
大部分速度差异可以归因于[.xts中执行的所有检查。即使没有这些检查,你应该预计[.xts比矩阵上的[稍微慢一些,因为xts对象总是需要做一个额外的操作:对索引进行子集化。
R> system.time(for(k in 1:10000) theMatrix[k, 1:10])
   user  system elapsed 
  0.012   0.000   0.015 
R> system.time(for(k in 1:10000)
+   .Call('_do_subset_xts', theXTS, k, 1:10, F, PACKAGE='xts'))
   user  system elapsed 
  0.016   0.000   0.018 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接