Avoid calling fmod twice in roundLayoutResultsToPixelGrid (#1775)

Summary:
X-link: https://github.com/facebook/litho/pull/1036

Pull Request resolved: https://github.com/facebook/yoga/pull/1775

X-link: https://github.com/facebook/react-native/pull/48404

## Changelog:
[Internal] -

This popped up when profiling some heavy UI performance, calling `fmod` operation in Yoga's `roundLayoutResultsToPixelGrid` in `PixelGrid.cpp` can be expensive, furthermore it turns out that some of the calls were redundant.

This replaces the duplicate calls to fmod with an equivalent single round operation, which for e.g. clang compiler on Windows brings the code in question from ~50 instructions (including 4 call instructions to the fmod function) down to ~30 instructions (without any external calls), and the layout operation being **~1% more efficient** for the particular benchmark I was looking into.

Reviewed By: christophpurrer

Differential Revision: D67689065

fbshipit-source-id: 2a074a1cb81bd7f7a3c414050b9ddda2ba90180f
This commit is contained in:
Ruslan Shestopalyuk
2024-12-30 12:38:48 -08:00
committed by Facebook GitHub Bot
parent 909e4bea6e
commit 91997d6cd3

View File

@@ -66,7 +66,8 @@ void roundLayoutResultsToPixelGrid(
yoga::Node* const node,
const double absoluteLeft,
const double absoluteTop) {
const auto pointScaleFactor = node->getConfig()->getPointScaleFactor();
const auto pointScaleFactor =
static_cast<double>(node->getConfig()->getPointScaleFactor());
const double nodeLeft = node->getLayout().position(PhysicalEdge::Left);
const double nodeTop = node->getLayout().position(PhysicalEdge::Top);
@@ -80,7 +81,7 @@ void roundLayoutResultsToPixelGrid(
const double absoluteNodeRight = absoluteNodeLeft + nodeWidth;
const double absoluteNodeBottom = absoluteNodeTop + nodeHeight;
if (pointScaleFactor != 0.0f) {
if (pointScaleFactor != 0.0) {
// If a node has a custom measure function we never want to round down its
// size as this could lead to unwanted text truncation.
const bool textRounding = node->getNodeType() == NodeType::Text;
@@ -96,12 +97,14 @@ void roundLayoutResultsToPixelGrid(
// We multiply dimension by scale factor and if the result is close to the
// whole number, we don't have any fraction To verify if the result is close
// to whole number we want to check both floor and ceil numbers
const double scaledNodeWith = nodeWidth * pointScaleFactor;
const bool hasFractionalWidth =
!yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 0) &&
!yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0);
!yoga::inexactEquals(round(scaledNodeWith), scaledNodeWith);
const double scaledNodeHeight = nodeHeight * pointScaleFactor;
const bool hasFractionalHeight =
!yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 0) &&
!yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0);
!yoga::inexactEquals(round(scaledNodeHeight), scaledNodeHeight);
node->setLayoutDimension(
roundValueToPixelGrid(