Open paleolimbot opened 1 year ago
Thank you for checking this out!! I very much appreciate your feedback :)) Some thoughts as I read along.
geos::geos
or s2::s2
etc repetitive and overly verbose. But I do now see your point! wk_handler()
by creating sfc geometries and converting from geo-types -> sfc and using the sfc handlerstopifnot()
. And since I know the output types of the functions (due to rust type system), I can specify the class at the end without loopinglines_tbl_wkb <- arrow::read_parquet(
"/Users/josiahparry/Downloads/ns-water-water_line-wkb.parquet"
)
vec_wkb <- wk::wkb(lines_tbl_wkb$geometry)
vec_sf <- sf::st_as_sfc(vec_wkb)
vec_geos <- geos::as_geos_geometry(vec_wkb)
vec_s2 <- s2::s2_geog_from_wkb(vec_wkb)
vec_rsgeo <- rsgeo::as_rsgeo(vec_sf)
bench::mark(
rsgeo::minimum_rotated_rect(vec_rsgeo),
geos::geos_minimum_rotated_rectangle(vec_geos),
check = FALSE
)
#> # A tibble: 2 × 6
#> expression min median `itr/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl>
#> 1 rsgeo::minimum_rotated_rect(vec_rsgeo) 1.99s 1.99s 0.501
#> 2 geos::geos_minimum_rotated_rectangle(vec_geos) 6.18s 6.18s 0.162
#> # ℹ 2 more variables: mem_alloc <bch:byt>, `gc/sec` <dbl>
bench::mark(
rsgeo::length_geodesic(vec_rsgeo),
s2::s2_length(vec_s2),
check = FALSE
)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt>
#> 1 rsgeo::length_geodesic(vec_rsgeo) 1.87s 1.87s 0.535 3.69MB
#> 2 s2::s2_length(vec_s2) 346.59ms 350.58ms 2.85 25.85MB
#> # ℹ 1 more variable: `gc/sec` <dbl>
I think there could be a big improvement if list ALTREP is used (probably here and in geos) that way there could be just 1 pointer instead of n.
..and s2. I'd like to build some abstractions around ALTREP soon because I've implemented it a few times and it's very difficult to get right and it's totally undocumented. It is a lot of work to do (I'm sure you know this) which is why I haven't gotten to it. It is also mostly not a problem for the sizes of data that are typically encountered in R (although that's a chicken-and-egg problem...people might work with bigger data if it wasn't so awful).
It's also quite nice because having the class attribute actually allows me to not loop over each geometry to figure out its type.
...except for all the operations that don't require a specific geometry (notably, subsetting: vec_rsgeo[stuff]
). You're making a bet that the unique geometry type will be accessed more than once, so pre-computing and caching it will pay off. Be very sure that this is the case before baking it in to the class
attribute! It would be safer would be to implement geometry_class_name()
...if in the future you want to implement the caching you can always update it to inspect the class name first.
I added parallelization to a few of these functions to pretend that they're faster now.
Cool! I've always wanted to do that with geos and s2...I imagine it's easier to code in rust. C++ doesn't have a built-in concept of a "thread pool" and I haven't kept up with the best ways to do this that don't involve vendoring huge swaths of unmaintainable C++.
Feel free to close, just sharing some of my experiments. This is very cool! I imagine you don't have much control over the benchmarks since you're mostly just connecting the wires for rust functions, plus, I find that benchmarking GEOS geometries is pretty difficult because putting that many external pointers into a
list()
makes the garbage collector go a little haywire, which may affect some things here.Any reason why you didn't prefix the functions? I mostly just typed
rsgeo::
to get the autocomplete (but maybe that's what you were aiming for).It might be nice (and considerably faster) if your rectangle-producing functions produced a
wk_rct()
? This would get themplot()
,st_as_sf()
, etc. for free (plus lets you propagate the CRS to whatever consumes the result).Is the geometry type as part of the class member (e.g.,
rs_GEOMETRYCOLLECTION
) necessary? It seems like it may be more efficient to only resolve the unique geometry types when required rather than loop over the result every time to build up this information?Created on 2023-08-27 with reprex v2.0.2