Производительность чтения R data.table с colClasses и без них

avatar
Imtiaz
8 августа 2021 в 18:38
87
0
0

Мне нужно придумать скрипт, который задает операцию сравнения между двумя векторами (чтобы найти количество несовпадающих значений). Первый вектор является вектором символов (может меняться). Этот набор будет сравниваться с 3000 других векторов, считанных из CSV-файлов. Все файлы csv представляют собой только один столбец и содержат уникальные значения. Каждый файл имеет размер от 1 до 60 МБ.

Я использую data.table fread для чтения CSV-файлов. Однако я вижу, что использование параметра colClasses для чтения значений в виде символов значительно увеличивает время выполнения скрипта. В приведенном ниже сценарии вариант 1 занимает около 10 секунд, а вариант 2 — около 120 секунд. Я хочу читать столбцы как символы. Почему эта разница? Не должно ли чтение занимать больше времени, если для определения типа приходится анализировать значения? Кроме того, как я могу ускорить чтение, сохраняя тип как символ?

Код:

path <- "data/processed_data"
file_names <- list.files(here(path), pattern="csv")
v <- c("one", "two", "three")
v_count_unmatched <- integer()
  
for (fn2 in file_names) {
    f2 <- data.table::fread(here(path, fn2)) #### Option 1
    #f2 <- data.table::fread(here(path, fn2), colClasses = 'character') #### Option 2
    v_count_unmatched      <- c(v_count_unmatched, length(setdiff(v,f2 %>% pull() )))
}

Я использую data.table версии 1.13.6. Спасибо.

Источник
IceCreamToucan
8 августа 2021 в 18:43
2

Вы уверены, что это часть fread, которая становится медленнее? Я думаю, что вычисление setdiff между векторами символов будет медленнее, чем для числовых векторов, возможно, поэтому изменение делает скрипт медленнее. В RStudio вы можете использовать Tools > Profile Selected Lines, чтобы увидеть время для различных частей скрипта. Если все, что вам нужно, это количество разных значений, вам не нужен setdiff, вы можете сделать sum(!vec1 %in% vec2)

Imtiaz
8 августа 2021 в 18:45
0

Одним из виновников является прочитанная часть. потому что я сравнил его, комментируя также часть различий. Разница в секундах, которую я опубликовал, на самом деле без части diff.

Imtiaz
9 августа 2021 в 15:16
0

Извините, вопрос был немного некорректен. Я сравнивал только часть загрузки файлов (нигде не используя загруженные данные). Это могло привести к некоторой ленивой загрузке, из-за которой вариант 1 давал лучшие результаты. Я переделал это, используя данные, и разница не так уж драматична. Оба занимают значительное время (> 100 секунд).

Ответы (0)