Порог для использования объединения поверх слияния - PullRequest
0 голосов
/ 16 марта 2019

Насколько я понимаю, разница между функцией merge() (в базе R) и функциями join() plyr и dplyr заключается в том, что join() быстрее и эффективнее при работе с "большими" данными наборы.

Есть ли какой-нибудь способ определить порог для определения того, когда использовать join() над merge(), без использования эвристического подхода?

1 Ответ

3 голосов
/ 16 марта 2019

Я уверен, что вам будет трудно найти «жесткое и быстрое» правило, когда нужно переключаться с одной функции на другую. Как уже упоминали другие, в R есть набор инструментов, которые помогут вам измерить производительность. object.size и system.time - две такие функции, которые смотрят на использование памяти и время выполнения соответственно. Один общий подход состоит в том, чтобы измерить два непосредственно на произвольно расширяющемся наборе данных. Ниже приведена одна попытка этого. Мы создадим фрейм данных со столбцом «id» и случайным набором числовых значений, позволяя фрейму данных расти и измерять, как он изменяется. Я буду использовать inner_join здесь, как вы упомянули dplyr. Мы будем измерять время как прошедшее время.

library(tidyverse)

setseed(424)

#number of rows in a cycle
growth <- c(100,1000,10000,100000,1000000,5000000)

#empty lists
n <- 1
l1 <- c()
l2 <- c()

#test for inner join in dplyr
for(i in growth){
  x <- data.frame("id" = 1:i, "value" = rnorm(i,0,1))
  y <- data.frame("id" = 1:i, "value" = rnorm(i,0,1))

  test <- inner_join(x,y, by = c('id' = 'id'))
  l1[[n]] <- object.size(test)

  print(system.time(test <- inner_join(x,y, by = c('id' = 'id')))[3])
  l2[[n]] <- system.time(test <- inner_join(x,y, by = c('id' = 'id')))[3]

  n <- n+1

}

#empty lists
n <- 1
l3 <- c()
l4 <- c()

#test for merge
for(i in growth){
  x <- data.frame("id" = 1:i, "value" = rnorm(i,0,1))
  y <- data.frame("id" = 1:i, "value" = rnorm(i,0,1))

  test <- merge(x,y, by = c('id'))
  l3[[n]] <- object.size(test)
  # print(object.size(test))

  print(system.time(test <- merge(x,y, by = c('id')))[3])
  l4[[n]] <- system.time(test <- merge(x,y, by = c('id')))[3]

  n <- n+1

   }

#ploting output (some coercing may happen, so be it)
plot <- bind_rows(data.frame("size_bytes" = l3, "time_sec" = l4, "id" = "merge"), 
                  data.frame("size_bytes" = l1, "time_sec" = l2, "id" = "inner_join"))

plot$size_MB <- plot$size_bytes/1000000

ggplot(plot, aes(x = size_MB, y =time_sec, color = id)) + geom_line()

enter image description here

merge, кажется, работает хуже от ворот, но на самом деле стартует около ~ 20 МБ. Это последнее слово по этому вопросу? Нет. Но такое тестирование может дать вам представление о том, как выбрать функцию.

...