Brodie Gaslam
2018-Oct-03 01:13 UTC
[Rd] grDevices::convertColor and colorRamp(space='Lab') Performance Improvements
`grDevices::convertColor` performance can be improved by 30-300x with
small changes to the code. `colorRamp(space='Lab')` uses `convertColor`
so it too benefits from substantial performance gains.
`convertColor` vectorizes explicitly over the rows of the input color
matrix using `apply`. The level-1 patch [1] illustrates a possible
minimal set of changes to achieve this with just R matrix and vector
operations. The changes consist primarily of switching `if/else` to
`ifelse`, `c` to `cbind`, `sum` to `rowSums`, etc. This results in
speedups of 30-100x as shown in table 1:
to
from Apple RGB sRGB CIE RGB XYZ Lab Luv
Apple RGB NA 38.3 55.8 30.3 60.2 56.3
sRGB 38.7 NA 55.7 36.5 62.9 52.7
CIE RGB 45.2 44.4 NA 30.6 51.5 43.1
XYZ 73.4 57.5 69.1 NA 92.2 69.0
Lab 46.6 56.6 65.4 72.0 NA 61.3
Luv 73.2 107.3 67.3 105.8 97.8 NA
## Table 1:
## Ratios of `grDevices` to 'level-1' patch speeds for 8000 colors
## from each supported color space to all other supported color spaces.
A few incremental changes as detailed in the level-2 patch [2] yield
additional performance improvements:
to
from Apple RGB sRGB CIE RGB XYZ Lab Luv
Apple RGB NA 97.1 106.2 89.0 117 83.4
sRGB 92.5 NA 99.4 86.4 120 76.0
CIE RGB 119.2 184.2 NA 82.2 135 83.4
XYZ 122.3 209.8 140.9 NA 171 148.8
Lab 166.4 168.2 255.4 288.5 NA 265.1
Luv 141.7 173.6 279.6 310.1 195 NA
## Table 2:
## Ratios of `grDevices` to level-2 patch speeds for 8000 colors
## from each supported color space to all other supported color spaces.
Not shown here is that the patched versions of `convertColor` are faster
with small inputs as well, though the difference is less marked.
I have posted tests on github [3], along with the results of running
them on my system [4]. While these tests are not proof that the patches
do not change the function other than to make it faster, the tests
results combined with the narrow scope of the changes hopefully provides
sufficient evidence this is the case. For those wanting to run the
tests, installation and testing instructions are on the github landing
page for this project [5].
There are some minor (in my opinion) changes in behavior that need to be
discussed:
* Inputs that would previously stop with errors or work inconsistently
now work consistently (e.g. zero-row inputs or inputs containing
NA/NaN/Inf).
* Column names are consistently set to the color space initials; these
were previously inconsistently set / mangled by `c`.
These are discussed at length with examples in [6].
It would be possible to preserve the existing behavior, but doing so
would require some contortions that serve no other purposes than that.
Additionally, in many cases the existing behavior is inconsistent across
different input/output color spaces. Finally, most of the differences
involve corner case inputs such as those containing NA/NaN/Inf, or zero
rows.
I am entirely amenable to modify the patches to preserve existing
behavior in these cases if that is considered desirable.
These patches should be coordinated with #17473 [7], which I found while
working on this issue.
-----------------------------------------------
'level-1' patch:
[1]:
https://raw.githubusercontent.com/brodieG/grDevices2/level-2/extra/level-1.txt
'level-2' patch:
[2]:
https://raw.githubusercontent.com/brodieG/grDevices2/level-2/extra/level-2.txt
Tests on github, and the result of running them:
[3]: https://github.com/brodieG/grDevices2/blob/level-2/tests/convertColor.R
[4]:
https://raw.githubusercontent.com/brodieG/grDevices2/level-2/tests/convertColor.Rout
Github landing page for this project:
[5]: https://github.com/brodieG/grDevices2
Discussion of differences introduces by patches:
[6]:
https://htmlpreview.github.io/?https://raw.githubusercontent.com/brodieG/grDevices2/level-2/extra/differences.html
Indirectly related bugzilla issue #17473:
[7]: https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17473
Paul Murrell
2018-Oct-03 22:09 UTC
[Rd] [FORGED] grDevices::convertColor and colorRamp(space='Lab') Performance Improvements
Thanks Brodie. Having a look at all of this is on my list. Paul On 03/10/18 14:13, Brodie Gaslam via R-devel wrote:> `grDevices::convertColor` performance can be improved by 30-300x with > small changes to the code.? `colorRamp(space='Lab')` uses `convertColor` > so it too benefits from substantial performance gains. > > `convertColor` vectorizes explicitly over the rows of the input color > matrix using `apply`. The level-1 patch [1] illustrates a possible > minimal set of changes to achieve this with just R matrix and vector > operations.? The changes consist primarily of switching `if/else` to > `ifelse`, `c` to `cbind`, `sum` to `rowSums`, etc. This results in > speedups of 30-100x as shown in table 1: > > ?????????? to > from??????? Apple RGB? sRGB CIE RGB?? XYZ? Lab? Luv > ? Apple RGB??????? NA? 38.3??? 55.8? 30.3 60.2 56.3 > ? sRGB?????????? 38.7??? NA??? 55.7? 36.5 62.9 52.7 > ? CIE RGB??????? 45.2? 44.4????? NA? 30.6 51.5 43.1 > ? XYZ??????????? 73.4? 57.5??? 69.1??? NA 92.2 69.0 > ? Lab??????????? 46.6? 56.6??? 65.4? 72.0?? NA 61.3 > ? Luv??????????? 73.2 107.3??? 67.3 105.8 97.8?? NA > > ## Table 1: > ## Ratios of `grDevices` to 'level-1' patch speeds for 8000 colors > ## from each supported color space to all other supported color spaces. > > A few incremental changes as detailed in the level-2 patch [2] yield > additional performance improvements: > > ?????????? to > from??????? Apple RGB? sRGB CIE RGB?? XYZ Lab?? Luv > ? Apple RGB??????? NA? 97.1?? 106.2? 89.0 117? 83.4 > ? sRGB?????????? 92.5??? NA??? 99.4? 86.4 120? 76.0 > ? CIE RGB?????? 119.2 184.2????? NA? 82.2 135? 83.4 > ? XYZ?????????? 122.3 209.8?? 140.9??? NA 171 148.8 > ? Lab?????????? 166.4 168.2?? 255.4 288.5? NA 265.1 > ? Luv?????????? 141.7 173.6?? 279.6 310.1 195??? NA > > ## Table 2: > ## Ratios of `grDevices` to level-2 patch speeds for 8000 colors > ## from each supported color space to all other supported color spaces. > > Not shown here is that the patched versions of `convertColor` are faster > with small inputs as well, though the difference is less marked. > > I have posted tests on github [3], along with the results of running > them on my system [4].? While these tests are not proof that the patches > do not change the function other than to make it faster, the tests > results combined with the narrow scope of the changes hopefully provides > sufficient evidence this is the case.?? For those wanting to run the > tests, installation and testing instructions are on the github landing > page for this project [5]. > > There are some minor (in my opinion) changes in behavior that need to be > discussed: > > * Inputs that would previously stop with errors or work inconsistently > now work consistently (e.g. zero-row inputs or inputs containing > NA/NaN/Inf). > * Column names are consistently set to the color space initials; these > were previously inconsistently set / mangled by `c`. > > These are discussed at length with examples in [6]. > > It would be possible to preserve the existing behavior, but doing so > would require some contortions that serve no other purposes than that. > Additionally, in many cases the existing behavior is inconsistent across > different input/output color spaces.? Finally, most of the differences > involve corner case inputs such as those containing NA/NaN/Inf, or zero > rows. > > I am entirely amenable to modify the patches to preserve existing > behavior in these cases if that is considered desirable. > > These patches should be coordinated with #17473 [7], which I found while > working on this issue. > > ----------------------------------------------- > > 'level-1' patch: > [1]: > https://raw.githubusercontent.com/brodieG/grDevices2/level-2/extra/level-1.txt > > > 'level-2' patch: > [2]: > https://raw.githubusercontent.com/brodieG/grDevices2/level-2/extra/level-2.txt > > > Tests on github, and the result of running them: > [3]: > https://github.com/brodieG/grDevices2/blob/level-2/tests/convertColor.R > [4]: > https://raw.githubusercontent.com/brodieG/grDevices2/level-2/tests/convertColor.Rout > > > Github landing page for this project: > [5]: https://github.com/brodieG/grDevices2 > > Discussion of differences introduces by patches: > [6]: > https://htmlpreview.github.io/?https://raw.githubusercontent.com/brodieG/grDevices2/level-2/extra/differences.html > > > Indirectly related bugzilla issue #17473: > [7]: https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17473 > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel-- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 paul at stat.auckland.ac.nz http://www.stat.auckland.ac.nz/~paul/
Possibly Parallel Threads
- Possible bug with chromatic adaptation in grDevices::convertColor
- grDevices::convertColor XYZ space is it really xyY?
- Alpha channel in colorRamp() and colorRampPalette()
- color scale mapped to B/W
- [R] color palette from red to blue passing white (shifted from R-help)