В качестве тривиального примера, скажем, мне интересно вычислить:
r = v*M^t
Где r и v - векторы, а M - чрезвычайно большая разреженная матрица.
Я могу решить это одним из двух способов:
r = v*(M*M*M*M...)
r = ((((v*M)M)M)M)...
Там, где первый подход приводит к получению промежуточных плотных матриц, которые нецелесообразно хранить в ОЗУ (для моего целевого минимального варианта использования мне понадобится как минимум 10 терабайт). Второе решение, напротив, всегда приводит к промежуточным векторам, и на самом деле оно работает на практике.
Проблема заключается в том, что при больших значениях t выделение памяти вызывает существенное узкое место в производительности.
library(pryr)
n = 20000
v = 1:n
M = matrix(1:(n*n), n) # Not a sparse matrix like my use case, but easier to start with
for (i in 1:10) {
v = v %*% M
print(address(v))
}
Как показывает функция address (), v перераспределяется при каждой итерации. Он не изменяется на месте. Распределение памяти не только замедляет работу, но, согласно profvis, сборщик мусора также постоянно вызывается и занимает большую часть времени.
Итак, мой вопрос: есть ли способ выполнить это вычисление (и, возможно, другие подобные ему) в R без лишних выделений памяти и вызовов gc (), происходящих под капотом?