Skip to content

Commit 6dd4195

Browse files
rshestfacebook-github-bot
authored andcommitted
Avoid calling fmod twice in roundLayoutResultsToPixelGrid (facebook#48404)
Summary: X-link: facebook/litho#1036 X-link: facebook/yoga#1775 Pull Request resolved: facebook#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
1 parent 7e665d4 commit 6dd4195

File tree

1 file changed

+9
-6
lines changed
  • packages/react-native/ReactCommon/yoga/yoga/algorithm

1 file changed

+9
-6
lines changed

packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ void roundLayoutResultsToPixelGrid(
6666
yoga::Node* const node,
6767
const double absoluteLeft,
6868
const double absoluteTop) {
69-
const auto pointScaleFactor = node->getConfig()->getPointScaleFactor();
69+
const auto pointScaleFactor =
70+
static_cast<double>(node->getConfig()->getPointScaleFactor());
7071

7172
const double nodeLeft = node->getLayout().position(PhysicalEdge::Left);
7273
const double nodeTop = node->getLayout().position(PhysicalEdge::Top);
@@ -80,7 +81,7 @@ void roundLayoutResultsToPixelGrid(
8081
const double absoluteNodeRight = absoluteNodeLeft + nodeWidth;
8182
const double absoluteNodeBottom = absoluteNodeTop + nodeHeight;
8283

83-
if (pointScaleFactor != 0.0f) {
84+
if (pointScaleFactor != 0.0) {
8485
// If a node has a custom measure function we never want to round down its
8586
// size as this could lead to unwanted text truncation.
8687
const bool textRounding = node->getNodeType() == NodeType::Text;
@@ -96,12 +97,14 @@ void roundLayoutResultsToPixelGrid(
9697
// We multiply dimension by scale factor and if the result is close to the
9798
// whole number, we don't have any fraction To verify if the result is close
9899
// to whole number we want to check both floor and ceil numbers
100+
101+
const double scaledNodeWith = nodeWidth * pointScaleFactor;
99102
const bool hasFractionalWidth =
100-
!yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 0) &&
101-
!yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0);
103+
!yoga::inexactEquals(round(scaledNodeWith), scaledNodeWith);
104+
105+
const double scaledNodeHeight = nodeHeight * pointScaleFactor;
102106
const bool hasFractionalHeight =
103-
!yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 0) &&
104-
!yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0);
107+
!yoga::inexactEquals(round(scaledNodeHeight), scaledNodeHeight);
105108

106109
node->setLayoutDimension(
107110
roundValueToPixelGrid(

0 commit comments

Comments
 (0)