WLED icon indicating copy to clipboard operation
WLED copied to clipboard

Reduce segment copies

Open TripleWhy opened this issue 8 months ago • 11 comments

Use move instead of copy where possible, avoid complexity/memory usage of full copies in other locations.

(Currently, this version would compile with deleted Segment copy functions.)

From the json/differs commit:

Move segment json-specific segment diffing to json.cpp

  • Avoid calling Segment copy constructor and destructor. This is fine as long as we only read primitive values.
  • Only diff stuff we are actually interested in.
  • Only diff stuff if it has an effect.

Note that the json copy code is effectively very similar to before, because the copy constructor also does a memcpy, plus additional work.

About applyValuesToSelectedSegs:
This could be simplified a lot, if we were to alter the behavior such that all selected segments would be modified unconditionally. Which would also address this function comment:

// problem: if the first selected segment already has the value to be set, other selected segments are not updated

Summary by CodeRabbit

  • Refactor

    • Streamlined LED segment update and management logic for more efficient operations and smoother effect transitions.
    • Improved logic for handling segment comparisons and updates, enhancing performance and readability.
    • Refactored segment handling to utilize in-place construction, optimizing performance during segment management.
  • New Features

    • Replaced segment appending method with a more efficient in-place construction approach.

TripleWhy avatar Mar 01 '25 10:03 TripleWhy

Walkthrough

The pull request renames the appendSegment method to emplaceSegment in the WS2812FX class to reflect emplacement semantics. It refactors segment initialization logic in resetSegments, simplifies segment difference checking by removing boolean flags and bitmask comparisons in JSON deserialization, and updates segment creation calls accordingly. The LED module's segment property updates are streamlined, and UDP segment addition uses the new emplacement method.

Changes

File(s) Change Summary
wled00/FX.h Renamed WS2812FX::appendSegment to emplaceSegment without changing parameters or logic.
wled00/FX_fcn.cpp Modified WS2812FX::resetSegments to replace a conditional emplace_back call with explicit if-else calls based on isMatrix for clearer segment initialization.
wled00/json.cpp Removed three boolean fields from SegmentCopy. Changed differs to return a boolean instead of bitmask, simplifying difference detection. Updated deserializeSegment signature and replaced appendSegment with emplaceSegment. Removed detailed difference tracking logic.
wled00/led.cpp Refactored applyValuesToSelectedSegs() to precompute colors once and update all selected segments unconditionally, simplifying logic and state change tracking.
wled00/udp.cpp Replaced strip.appendSegment() with strip.emplaceSegment() in parseNotifyPacket when adding new segments, maintaining existing control flow.

📜 Recent review details

Configuration used: CodeRabbit UI Review profile: CHILL Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d2ac3a780e24eca7c5511098e3549cdcaf97273 and 46bee5ad7bdeab03100d2068fe4afc15cf60ebf8.

📒 Files selected for processing (5)
  • wled00/FX.h (1 hunks)
  • wled00/FX_fcn.cpp (1 hunks)
  • wled00/json.cpp (5 hunks)
  • wled00/led.cpp (1 hunks)
  • wled00/udp.cpp (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • wled00/udp.cpp
  • wled00/FX_fcn.cpp
🚧 Files skipped from review as they are similar to previous changes (3)
  • wled00/led.cpp
  • wled00/FX.h
  • wled00/json.cpp
⏰ Context from checks skipped due to timeout of 90000ms (19)
  • GitHub Check: wled_build / Build Environments (usermods)
  • GitHub Check: wled_build / Build Environments (esp32s3_4M_qspi)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_8MB_opi)
  • GitHub Check: wled_build / Build Environments (esp32dev_V4)
  • GitHub Check: wled_build / Build Environments (esp32_wrover)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_compat)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full_160)
  • GitHub Check: wled_build / Build Environments (esp32_eth)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_compat)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
  • GitHub Check: wled_build / Build Environments (lolin_s2_mini)
  • GitHub Check: wled_build / Build Environments (esp32c3dev)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full_compat)
  • GitHub Check: wled_build / Build Environments (esp32dev)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_160)
  • GitHub Check: wled_build / Build Environments (esp8266_2m)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_160)
  • GitHub Check: wled_build / Build Environments (nodemcuv2)
✨ Finishing Touches
  • [ ] 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

coderabbitai[bot] avatar Mar 01 '25 10:03 coderabbitai[bot]

Updated applyValuesToSelectedSegs to the suggested logic.

Removed all copy and diff code from json code, based on this assumption: https://github.com/wled/WLED/pull/4580#issuecomment-2692654622

TripleWhy avatar Mar 05 '25 09:03 TripleWhy

based on this assumption: #4580 (comment)

This is actually a bug in the setOption() code. If the on state didn't change so shouldn't stateChanged. setOption() is used to force transition for changes of on (or power) state. In the past it was used to set other bitfields which are now accessible directly (but such change does not invoke startTransition()).

So, IMO, differs() should stay. However, there is no need to copy entire segment as currently implemented since only segment attributes are compared.

blazoncek avatar Mar 06 '25 18:03 blazoncek

I can remove the commit that removes the differs function from this PR.

However, there is no need to copy entire segment as currently implemented since only segment attributes are compared.

I'm not sure what you are saying here. Are you favoring the version I had in this PR or the version from the other PR?

TripleWhy avatar Mar 07 '25 10:03 TripleWhy

I am just trying to clarify. I did like the solution in https://github.com/wled/WLED/pull/4578/commits/90a49c5a072c668a8c855beb765e029d79821e34

These: stateChanged and stateUpdated() or (God forbid) colorUpdated() are all helpers to (mostly) keep legacy code happy. If you are curious, I don't like any of them.

blazoncek avatar Mar 07 '25 10:03 blazoncek

Removed 4d2ac3a780e24eca7c5511098e3549cdcaf97273, this should be what you want

TripleWhy avatar Mar 07 '25 10:03 TripleWhy

is this PR still relevant with the new layering code?

DedeHai avatar Jun 05 '25 18:06 DedeHai

I do not think it is as layer blending did reduce segment copies in a similar way as this PR.

blazoncek avatar Jun 06 '25 04:06 blazoncek

Merged main into this PR, and if you look at the diff now, there isn't really much left of the actual reduction, just some general adjustments

TripleWhy avatar Jun 06 '25 12:06 TripleWhy

I glanced over it, to me it looks like no change at all apart from som re-factoring which is kind of arbitrary / personal style.

DedeHai avatar Jun 06 '25 12:06 DedeHai

All of these changes are clearly improvements, but yes, most of them are minor, and don't affect the number of segment copies

TripleWhy avatar Jun 06 '25 12:06 TripleWhy

Hey! This pull request has been open for quite some time without any new comments now. It will be closed automatically in a week if no further activity occurs. Thank you for contributing to WLED! ❤️

github-actions[bot] avatar Oct 05 '25 12:10 github-actions[bot]