Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Implement encode_native() without going through the character vector #35

Closed
wants to merge 18 commits into from

Conversation

zeehio
Copy link

@zeehio zeehio commented Sep 8, 2022

Hi,

Thanks for your farver package. It's nice to have efficient color conversion in R.

I am opening this pull request that improves the performance of encode_native() by avoiding creating an intermediate character vector with the colours.

Here I compare the performance on a 10 million length vector (e.g. from a 10k x 1000 matrix):

library(farver)
x <- runif(1E7)
ramp <- scales::colour_ramp(c("red", "blue"))
colours_chr <- ramp(x)
spectrum <- farver::decode_colour(colours_chr)

bench::mark(
  before = {
    # This was how encode_native worked before
    cols <- encode_colour(spectrum, alpha = 0.75)
    farver:::encode_native(cols)
  },
  after = {
    farver::encode_native(spectrum,alpha = 0.75)
  }
)
#> # A tibble: 2 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 before         1.2s     1.2s     0.834   114.5MB     0   
#> 2 after        94.1ms   95.5ms    10.5      38.1MB     2.62

Created on 2022-09-12 by the reprex package (v2.0.1)

The advantage on such a large vector is of a factor of 10. On a 1k long vector, my implementation is 5x faster.

I just discovered nativeRaster objects and I find them super useful for plotting large matrices (in a way similar to what image, filled.contour or annot_raster do). I find those functions slower than what they actually need to be, and I am trying to make a ggplot extension able to provide a nice API and an efficient implementation.

This is my first step towards that goal.

I would appreciate a lot your feedback on this contribution.

This includes passing the colours as a data frame, with three (or four)
columns.

This approach avoids coercing all channels to a single matrix,
(avoiding memory allocations and copying data around).

Tests that cover encoding from any colour space directly to native
have also been added.

The handling of encoding input (matrix/list of colours and alpha vector)
has been refactored into functions, as well as the parsing of the
alpha colour (with its NA handling).
Useful for merging alpha information into a native colour
zeehio added a commit to zeehio/scales that referenced this pull request Sep 12, 2022
@zeehio zeehio changed the title Implement encode_native() without going through the character vector WIP: Implement encode_native() without going through the character vector Sep 13, 2022
@zeehio
Copy link
Author

zeehio commented Sep 18, 2022

Closing this to make easier-to-review pull requests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant