FastAsyncWorldEdit icon indicating copy to clipboard operation
FastAsyncWorldEdit copied to clipboard

Set Extent on the Copy -m Mask flag

Open Zeranny opened this issue 9 months ago • 10 comments

Overview

While developing ezEdits @eztaK-red and I noticed that not using a MaskTraverser to set the extent on a mask results in significantly slower performance.

We assumed that this could also be why we noticed slow performance in the -m flag for //copy, and that does appear to be the case.

There may be other instances of masks in FAWE not having an extent set where performance could be improved, but I didn't want to get ahead of myself in case there were issues with the way that I have fixed it here. Especially as during testing it appears older versions of FAWE (2.11.1) were even slower, so changes since then may have already had a positive impact on -m performance.

Description

Sets the extent for the finalMask in the createCopy() method used by //copy which (going by previous FAWE commits) avoids using a WorldWrapper.

Rough runtime comparison using -m #solid,>[!air],[/[0][90]],[|air] (Before & After fix): 2025-03-02_17 53 41 2025-03-02_18 03 13

Copying a large selection with a "complex" mask & pasting (After fix): 2025-03-02_17 35 57 2025-03-02_17 36 21

Submitter Checklist

  • [x] Make sure you are opening from a topic branch (/feature/fix/docs/ branch (right side)) and not your main branch.
  • [x] Ensure that the pull request title represents the desired changelog entry.
  • [x] New public fields and methods are annotated with @since TODO.
  • [x] I read and followed the contribution guidelines.

Zeranny avatar Mar 02 '25 17:03 Zeranny

Investigating a bit further:

Paper-1.20.6 (tested #151) or older:

  • newest FAWE (#1061): //copy -m: 52s
  • this-PR's FAWE version: //copy -m: <1s

Paper-1.21 (tested #103) or newer:

  • newest FAWE (#1061): //copy -m: <1s
  • this-PR's FAWE version: //copy -m: <1s

This bug, of //copy -m and //cut -m taking significantly longer than it should, appears to affect even the newest FAWE versions if they are running on Paper 1.20.6 or older.

Furthermore, somehow, it's much better when the server is running on 1.21, independent of the FAWE version.

eztaK-red avatar Mar 04 '25 17:03 eztaK-red

Re-activated this PR. I had set it back to draft as it was unclear exactly what scenarios led to slow performance. From my own testing it does appear that on MC 1.21.4 the performance for very large copies is still sometimes faster with this change, but that my be a bit random.

I would appreciate any further insight into the underlying performance difference :)

Zeranny avatar Mar 04 '25 17:03 Zeranny

I don't know if you tested that on the same FAWE build on the different versions, and also with the same configuration. There were quite a few changes in the last months that could affect performance. Can you provide profiles (e.g. through spark, or the IntelliJ profiler) especially of the slow case?

Other than that: Would it make sense to move your change into setSourceMask instead?

SirYwell avatar Mar 04 '25 17:03 SirYwell

1.21 (fast case): https://spark.lucko.me/EjX9IPlk75 1.20.6 (slow case): https://spark.lucko.me/T0zzmO5OQx

eztaK-red avatar Mar 04 '25 18:03 eztaK-red

Hm, from a quick look, I assume that chunks are loaded in the fast case but not in the slow one. Could that be the case?

SirYwell avatar Mar 04 '25 18:03 SirYwell

Is it that in 1.20.6 net.minecraft.world.level.Level.getChunk() calls net.minecraft.world.level.ServerChunkCache.getChunk() Screenshot_20250304_193942

while in 1.21 net.minecraft.world.level.Level.getChunk() calls net.minecraft.server.level.ServerChunkCache.getChunkAtIfLoadedImmediately() image ?

eztaK-red avatar Mar 04 '25 18:03 eztaK-red

Interesting - though it seems we currently directly access the world here, which is what we should avoid and what this PR addresses I guess.

SirYwell avatar Mar 04 '25 19:03 SirYwell

I will test out your suggestion to move this to setSourceMask tomorrow and update :)

Zeranny avatar Mar 04 '25 21:03 Zeranny

After taking a closer look, setSourceMask is probably not the right place. But we have similar code already here: https://github.com/IntellectualSites/FastAsyncWorldEdit/blob/f3860618ad157e406a8b6999348f8477317defbe/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java#L352-L355 This only affects situations with transformations involved, where https://github.com/IntellectualSites/FastAsyncWorldEdit/blob/f3860618ad157e406a8b6999348f8477317defbe/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java#L414-L420 is missing that part, basically. Adding it in that if would be good I think.

SirYwell avatar Mar 05 '25 13:03 SirYwell

@Zeranny bumping this

dordsor21 avatar Aug 01 '25 14:08 dordsor21