hadley/dplyr — pull request #326 by Errrriikkkk (2014-03-16 20:25:27+00:00)
Title: Speed up Inner Joins in some cases

When using a loop for an inner join, it is best that the LHS table has fewer rows than the RHS table http://msdn.microsoft.com/en-us/library/ms191318.aspx

I've implemented the check on the R side, but it should probably be done at the C++ side (although nrow is generally a cheap operation). I've also only implemented the generic for dispatch on data.frame arguments, and my test only checks equality, and not column ordering. That is, if a user specifies the data.frames in a certain order, he/she expects the columns come out in the same order.

Here is an example benchmark of when this matters:

```
x <- data.frame(a = 1:1000, b = runif(1000))
x <- x[sample(nrow(x), 1000, replace = FALSE), ]
y <- data.frame(a =sample(1000000, 1000000, replace = TRUE), d = runif(100000))

inner_join.data.frame1 <- function(x, y, by = NULL, copy = FALSE, ...) {
if (nrow(x) > nrow(y)) {
as.data.frame(inner_join(tbl_df(y), x, by = by, copy = copy, ...))
} else {
as.data.frame(inner_join(tbl_df(x), y, by = by, copy = copy, ...))
}
}
inner_join.data.frame <- function (x, y, by = NULL, copy = FALSE, ...)
{
as.data.frame(inner_join(tbl_df(x), y, by = by, copy = copy,
...))
}
microbenchmark(
inner_join(x, y, by = "a"),
inner_join(y, x, by = "a"),
inner_join.data.frame1(x, y, by = "a"),
inner_join.data.frame1(y, x, by = "a"),
times = 20
) -> res

>res
Unit: milliseconds
expr min lq median uq max neval
inner_join(x, y, by = "a") 33.38714 34.93284 35.79604 37.04650 41.51064 20
inner_join(y, x, by = "a") 747.09208 772.33268 785.33907 796.33719 810.32307 20
inner_join.data.frame1(x, y, by = "a") 33.93982 35.09669 35.54950 36.87811 180.41901 20
inner_join.data.frame1(y, x, by = "a") 33.41550 34.48303 35.12243 36.07360 37.58867 20
```