Я создаю матрицу, представляющую определенное значение для комбинации клиентов (строки) и функций (столбцы). Давайте назовем эту матрицу NBA. Основываясь на данных, полученных через API, эту матрицу нужно обновлять много раз каждую секунду, вставляя новые значения для каждого вызова с m [x, y] <- new_value. Впоследствии выполняются некоторые матричные операции (здесь это не важно). Матрица является частью объекта R6 как частное поле, а метод update_matrix позволяет обновить определенную ячейку матрицы. Однако эта операция очень медленная по сравнению с обновлением обычного матричного объекта вне R6, порядка микросекунд, а не наносекунд. </p>
Представляет:
library(bench)
library(ggplot2)
library(tidyr)
# Create NBA matrix, sparse
no_customers <- 1e6
no_features <- 30
NBA_matrix <-
matrix(
sample(c(rep(0, 1000), 1), size = no_customers * no_features, replace = TRUE),
nrow = no_customers,
ncol = no_features
)
# Create NBA_like R6 object with matrix
library(R6)
NBA_lite <- R6Class("NBA_lite",
public = list(
mm = NULL,
initialize = function(input_matrix) self$mm <- input_matrix,
get_matrix = function() self$mm,
modify = function(row, col, value) self$mm[row,col] <- value
)
)
new_NBA_lite <- NBA_lite$new(input_matrix = NBA_matrix)
# Benchmark modifying single value, matrix vs R6 field
bench::mark(matrix = NBA_matrix[234123, 10] <- 2,
R6_field = new_NBA_lite$modify(row = 234123, col = 10, value = 2))
expression median total_time
NBA_matrix[234123, 10] <- 2 804ns 8.84ms
new_NBA_lite$modify(row = 234123, col = 10, value = 2) 126ms 125.66ms
Из bench :: mark кажется, что использование метода R6 каждый раз запускает сборку мусора, что может объяснить добавленные ~ 120 мс.
Мне трудно понять это, так как я воспринимаю объекты R6 как среды передачи по ссылке, которые не должны подвергаться копированию при модификации и необходимости в сборке мусора.
PS : Та же самая задержка g c происходит при использовании S4 OOP в R.
Заранее спасибо