-
Notifications
You must be signed in to change notification settings - Fork 138
Avoid needless array allocation in rgb to hex conversion #1104
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
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
felixarntz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ju1ius Thank you for the PR, great catch!
I have one suggestion on how your logic could be further simplified, mostly easier to understand when reading the code.
| if ( ! ( | ||
| \is_int( $red ) && \is_int( $green ) && \is_int( $blue ) | ||
| && $red >= 0 && $red <= 255 | ||
| && $green >= 0 && $green <= 255 | ||
| && $blue >= 0 && $blue <= 255 | ||
| ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be further simplified by not having the entire clause negated.
| if ( ! ( | |
| \is_int( $red ) && \is_int( $green ) && \is_int( $blue ) | |
| && $red >= 0 && $red <= 255 | |
| && $green >= 0 && $green <= 255 | |
| && $blue >= 0 && $blue <= 255 | |
| ) ) { | |
| if ( | |
| ! is_int( $red ) || $red < 0 || $red > 255 | |
| || ! is_int( $green ) || $green < 0 || $green > 255 | |
| || ! is_int( $blue ) || $blue < 0 || $blue > 255 | |
| ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels weird to me.
// One would normally write A.
if (!isValid($r, $b, $b)) return null;
else return toHex($r, $g, $b);
// or B.
if (isValid($r, $b, $b)) return toHex($r, $g, $b);
else return null;
// but not C.
if (isInvalid($r, $b, $b)) return null;
else return toHex($r, $g, $b);
// and certainly not D.
if (!isInvalid($r, $b, $b)) return toHex($r, $g, $b);
else return null;If you really want to remove the negation, the most readable IMO would be option B:
if (
\is_int($r) && $r >= 0 && $r <= 255
&& \is_int($g) && $g >= 0 && $g <= 255
&& \is_int($b) && $b >= 0 && $b <= 255
) {
return sprintf('%02x%02x%02x', $r, $g, $b);
}
return null;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would agree with you if we had a function like isValid to call here, but since we don't have one, I think we shouldn't reason about readability / understandability based on a hypothetical function. Your option B would be okay from a readability perspective, but then it would no longer use an early return, which is a good convention to avoid a lot of nesting of if clauses.
So IMO it makes sense to either go with my suggestion, or introduce a separate function like your isValid that we can call here to simplify readability even more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ju1ius Will you be adding a function like dominant_color_is_valid_rgb()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, @westonruter.
The dominant_color_rgb_to_hex function currently has two call sites and in both of them the input is guaranteed to be valid RGB, so the validation steps are useless.
In the Imagick editor case, the ImagickPixel::getColor method guarantees that the r, g and b keys of the returned array are integers in the [0, 255] range.
In the GD editor case, the imagecolorat function returns int|false. The PHP type coercion rules and the following bit operations therefore guarantee that the $r, $g and $b variables are integers in the [0, 255] range.
Therefore my suggestion would be to just inline the sprintf calls, remove the dominant_color_rgb_to_hex function to reduce API surface, and optionally fix the error checking in the GD editor so that a WP_Error is returned instead of "000000".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for that. In 31fd033 I've added an explicit check to ensure that we only use the imagecolorat() return value if it is an int.
Also, note that in #1203 the use of PHP type hints is introduced so that this code can be simplified to:
if ( ! (
$red >= 0 && $red <= 255 &&
$green >= 0 && $green <= 255 &&
$blue >= 0 && $blue <= 255
) ) {There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've applied that simplification with fixing the merge conflict for that PR: 7e85330
… no-array-alloc * 'trunk' of https://github.com/WordPress/performance: (277 commits) Add comments explaining why PHPStan is ignored Fix function stub docs Add rememberPossiblyImpureFunctionValues:false to fix it_should_use_the_next_available_hash_for_the_full_size_image_on_multiple_image_edits Fix types for arguments passed in tests Ignore phpstan errors when testing for incorrect usage Bump PHPStan level to 5 Work around PHPStan not being aware of callback being called Improve specificity of assertions Remove assertions which are always true Eliminate ignoring phpstan error Fix offset does not exist on array in test Fix variable in empty() always exists and is not falsy Use function stub to override filtered return value typing Revert "Add typing for attachment metadata added by webp-uploads" Revert "Add typing for attachment metadata added by Dominant Color Images" Update comment to reference visibility instead of opacity Use visibility:hidden instead of opacity:0 Remove needless isset() check for function key in debug_backtrace() response Add treatPhpDocTypesAsCertain:false to fix 54 issues Bump PHPStan level to 4 ...
The current implementation of the
dominant_color_rgb_to_hexfunction validates the RGB color by:Which is not a very performant way to check if a variable is an integer in the range
[0..255].This PR replaces the current implementation by simple type checks and integer comparisons.