Skip to content

Instantly share code, notes, and snippets.

@mdsumner
Last active June 20, 2025 11:28
Show Gist options
  • Save mdsumner/049c365db354bb6aea0b1a00447adb00 to your computer and use it in GitHub Desktop.
Save mdsumner/049c365db354bb6aea0b1a00447adb00 to your computer and use it in GitHub Desktop.
rproj <- function() sprintf("+proj=laea +lon_0=%f +lat_0=%f", runif(1, -180, 180), runif(1, -90, 90))
pts <- geosphere::randomCoordinates(1e5)
ll <- function() "EPSG:4326"

library(terra)
library(sf)
terra_ <- function(x) {
  terra::project(x, to = rproj(), from = ll())
}
sf_ <- function(x) {
  sf::sf_project(pts, to = rproj(), from = ll())
}
reproj_ <- function(x) {
  reproj::reproj_xy(x, rproj(), source = ll())
}
wk_ <- function(x, trans) {
  ## everything else returns a matrix, so we're a bit unfair on wk here
  as.matrix(wk::wk_transform(wk::xy(x[,1, drop = TRUE], x[,2, drop = TRUE]), trans))
}
gdalraster_ <- function(x) {
  gdalraster::transform_xy(x, srs_to = rproj(), srs_from = ll())
}

PROJ_ <- function(x) {
  PROJ::proj_trans(x, rproj(), source_crs = ll())
}
proj4_ <- function(x) {
  proj4::ptransform(x * pi/180, dst.proj = rproj(), src.proj = ll())
}
system.time(x <- terra_(pts))
system.time(x <- sf_(pts))
system.time(x <- reproj_(pts))
trans <- PROJ::proj_trans_create(target_crs = rproj(), source_crs = ll())
system.time(x <- wk_(pts, trans))
system.time(x <- gdalraster_(pts))
colnames(pts) <- c("x", "y")
system.time(x <- PROJ_(pts))
system.time(x <- proj4_(pts))

rbenchmark::benchmark(terra = terra_(pts), 
                      sf = sf_(pts), 
                      reproj = reproj_(pts), 
                      wk = wk_(pts, trans), 
                      gdalraster = gdalraster_(pts),
                      PROJ = PROJ_(pts),
                      proj4 = proj4_(pts),
                      replications = 100) |> dplyr::arrange(relative)
@mdsumner
Copy link
Author

mdsumner commented Jun 20, 2025

        test replications elapsed relative user.self sys.self user.child sys.child
1         sf          100   1.960    1.000     1.915    0.047          0         0
2         wk          100   2.138    1.091     2.139    0.000          0         0
3      proj4          100   2.144    1.094     2.090    0.055          0         0
4 gdalraster          100   2.235    1.140     2.183    0.052          0         0
5       PROJ          100   2.695    1.375     2.636    0.061          0         0
6     reproj          100   3.309    1.688     3.256    0.055          0         0
7      terra          100   3.385    1.727     3.300    0.061          0         0

@mdsumner
Copy link
Author

with more points we start to differentiate a bit, gdalraster looking good (really there't not much point caring with these numbers, all are good)

        test replications elapsed relative user.self sys.self user.child sys.child
1         sf          100  11.799    1.000    11.748    0.056          0         0
2      proj4          100  12.810    1.086    12.758    0.056          0         0
3 gdalraster          100  13.631    1.155    13.569    0.066          0         0
4         wk          100  14.320    1.214    14.323    0.003          0         0
5       PROJ          100  16.857    1.429    16.785    0.079          0         0
6     reproj          100  19.176    1.625    19.117    0.067          0         0
7      terra          100  21.419    1.815    21.365    0.066          0         0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment