R - Почему добавление 1 столбца в таблицу данных почти удваивает пиковое использование памяти?

После полученияПомогите от 2 добрых джентльменов мне удалось переключиться на таблицы данных с фрейма данных + плир.

Ситуация и мои вопросы

Пока я работал, я заметил, чтопиковое использование памяти почти вдвое увеличился с 3,5 ГБ до 6,8 ГБ (согласно Windows Task Manager), когда я добавил 1 новый столбец, используя:= к моему набору данных, содержащему ~ 200K строк по 2,5K столбцов.

Затем я попытался 200M строки на 25 col, увеличение было с 6 ГБ до 7,6 ГБ до падения до 7,25 ГБ послеgc().

Что касается добавления новых столбцов, сам Мэтт Доул упомянулВот тот:

С его оператором: = вы можете:

Add columns by reference
Modify subsets of existing columns by reference, and by group by reference
Delete columns by reference

Ни одна из этих операций вообще не копирует (потенциально большой) data.table, даже один раз.

Вопрос 1: зачем добавлять один столбец «NA» для DT с 2,5K столбцамидвойной пиковая память используется, если data.table вообще не копируется?

Вопрос 2: Почему удвоение не происходит, когда DT составляет 200M x 25? Я не включил экран печати для этого, но не стесняйтесь изменить мой код и попробовать.

Печатные экраны для использования памяти с использованием тестового кода

Чистая перезагрузка, RStudio и MS Word открыты - используется 103 МБ

После запуска кода создания DT, но до добавления столбца - используется 3,5 ГБ

После добавления 1 столбца, заполненного NA, но перед gc () - используется 6,8 ГБ

После запуска gc () - используется 3,5 ГБ

Тестовый код

Чтобы исследовать, я сделал следующий тестовый код, который близко имитирует мой набор данных:

library(data.table)
set.seed(1)

# Credit: Dirk Eddelbuettel's answer in 
# https://stackoverflow.com/questions/14720983/efficiently-generate-a-random-sample-of-times-and-dates-between-two-dates
RandDate <- function(N, st="2000/01/01", et="2014/12/31") { 
  st <- as.POSIXct(as.Date(st))
  et <- as.POSIXct(as.Date(et))
  dt <- as.numeric(difftime(et,st,unit="sec"))
  ev <- runif(N, 0, dt)
  rt <- as.character( strptime(st + ev, "%Y-%m-%d") )
}

# Create Sample data
TotalNoCol <- 2500
TotalCharCol <- 3
TotalDateCol <- 1
TotalIntCol <- 600
TotalNumCol <- TotalNoCol - TotalCharCol - TotalDateCol - TotalIntCol
nrow <- 200000

ColNames = paste0("C", 1:TotalNoCol)

dt <- as.data.table( setNames( c(

  replicate( TotalCharCol, sample( state.name, nrow, replace = T ), simplify = F ), 
  replicate( TotalDateCol, RandDate( nrow ), simplify = F ), 
  replicate( TotalNumCol, round( runif( nrow, 1, 30 ), 2), simplify = F ), 
  replicate( TotalIntCol, sample( 1:10, nrow, replace = T ), simplify = F ) ), 

    ColNames ) )

gc()

# Add New columns, to be run separately
dt[, New_Col := NA ]  # Additional col; uses excessive memory?

Исследования завершены

Я не нашел слишком много дискуссий об использовании памяти для DT с большим количеством столбцов, толькоэтот но даже тогда речь идет не о памяти.

В большинстве дискуссий по использованию большого набора данных + память используются DT с очень большим количеством строк, но с относительно небольшим числом столбцов.

Моя система

Intel i7-4700 с 4-ядерным / 8-потоковым; 16 ГБ оперативной памяти DDR3-12800; Windows 8.1 64-битная; Жесткий диск 500 ГБ 7200 об / мин; 64-битный R; Таблица данных, версия 1.9.4

Отказ от ответственности

Прошу прощения за использование метода «не R» (т. Е. Диспетчера задач) для измерения используемой памяти. Измерение / профилирование памяти в R - это то, что я до сих пор не понял.

Изменить 1: После обновления до таблицы данных версии 1.9.5 и повторного запуска. Проблема сохранилась, к сожалению.

Ответы на вопрос(1)

Ваш ответ на вопрос