refactor(mask): simplify MaskUtil::getDataMaskBit implementation#226
refactor(mask): simplify MaskUtil::getDataMaskBit implementation#226DASPRiD merged 7 commits intoBacon:mainfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #226 +/- ##
============================================
- Coverage 71.95% 71.81% -0.14%
+ Complexity 996 995 -1
============================================
Files 49 49
Lines 3170 3151 -19
============================================
- Hits 2281 2263 -18
+ Misses 889 888 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
About replacing Quick benchmark code - unsignedRightShift method call vs integer divisionclass BitUtils {
public static function unsignedRightShift(int $a, int $b): int
{
return (
$a >= 0
? $a >> $b
: (($a & 0x7fffffff) >> $b) | (0x40000000 >> ($b - 1))
);
}
}
function bench(callable $fn, int $iterations = 1_000_000): string {
$start = microtime(true);
$sum = 0;
for ($i = 0; $i < $iterations; ++$i) {
$y = ($i & 0xFFFF) - 32768; // includes negatives
$sum += $fn($y);
}
return number_format(microtime(true) - $start, 3);
}
$timeStaticMethod = bench(function($y) {
return BitUtils::unsignedRightShift($y, 1);
});
$timeInline = bench(function($y) {
return ($y >= 0)
? ($y >> 1)
: (($y & 0x7fffffff) >> 1) | 0x40000000;
});
$timeOptimized = bench(function($y) {
return ($y >> 1) & 0x7fffffff;
});
$timeDivision = bench(function($y) {
return (int) ($y / 2);
});
$timeIntdiv = bench(function($y) {
return intdiv($y, 2);
});
echo "Static method shift: {$timeStaticMethod} sec\n";
echo "Inline unsigned shift: {$timeInline} sec\n";
echo "Optimized unsigned shift: {$timeOptimized} sec\n";
echo "Integer division: {$timeDivision} sec\n";
echo "intdiv(): {$timeIntdiv} sec\n";Results:
|
Simpler and saves the method call overhead.
As there is now a dedicated function intdiv() for this operation, let's use it.
The bitmask is marginally faster, but modulo makes the intent clearer.
…atchError The PHP match expression throws an UnhandledMatchError when no arm matches. Removing the custom exception simplifies the code and aligns with the behavior discussed in Bacon#200.
This was the only remaining loose comparison in the entire repository.
|
I assume other places which use unsignedRightShift cannot be modified the same way? |
|
This simplification only works when the value being shifted is guaranteed to be non‑negative. For non‑negative inputs, But if the input can be negative, logical right shift and arithmetic right shift diverge, so those cases can’t be simplified in the same straightforward way. |
There was a problem hiding this comment.
Pull request overview
Refactors MaskUtil::getDataMaskBit() to simplify mask-bit computation logic in the QR encoder, replacing the prior switch/bitwise implementation with a match expression and integer division.
Changes:
- Replaced
switch-based mask selection with a PHPmatchexpression. - Removed dependency on
BitUtils::unsignedRightShift()in favor ofintdiv(). - Dropped
InvalidArgumentExceptionhandling/documentation for invalid mask patterns.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
thanks! |
Several simplifications in the
MaskUtil::getDataMaskBitimplementation, the most significant ones being:BitUtils::unsignedRightShiftwith straightforward integer divisionmatchexpression