Changeset 19214 in josm


Ignore:
Timestamp:
2024-09-09T17:55:46+02:00 (6 months ago)
Author:
taylor.smock
Message:

Fix #23908: Significantly improve the performance of copy/paste when dealing with large amounts of data

From #23908, at least one valid workflow involves copy/pasting large amounts of
data (specifically updating boundaries). The relation for Terwolde in the
sample data had 2206 objects. This took >5 minutes to copy between layers. With
this change, it takes <1 second.

This is a performance regression from r19176. The primary culprit from r19176 is
when we check the size of the dataset. The problem is that we check to see if the
size of the primitives being changed is greater than or equal to the non-deleted
complete primitives in the dataset. We get a new filtered collection each time
we get those primitives, and therefore the size of that is not cached. The size
calculation for the filtered collection is where almost all the expense is. We
fix that by wrapping the work from AddPrimitivesCommand in DataSet#update to
have a single large update at the end of the copy operation. This ensures that
we do not have many spurious fired event calls when a mass operation is going on.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/command/AddPrimitivesCommand.java

    r18801 r19214  
    1010import java.util.Optional;
    1111import java.util.stream.Collectors;
    12 
    13 import javax.swing.Icon;
    1412
    1513import org.openstreetmap.josm.data.osm.DataSet;
     
    6967    public boolean executeCommand() {
    7068        DataSet ds = getAffectedDataSet();
     69        ds.update(() -> this.executeRealCommand(ds));
     70        if (toSelect != null) {
     71            ds.setSelected(toSelect.stream().map(ds::getPrimitiveById).collect(Collectors.toList()));
     72        }
     73        return true;
     74    }
     75
     76    private void executeRealCommand(DataSet ds) {
    7177        if (createdPrimitives == null) { // first time execution
    7278            List<OsmPrimitive> newPrimitives = new ArrayList<>(data.size());
     
    110116            }
    111117        }
    112         if (toSelect != null) {
    113             ds.setSelected(toSelect.stream().map(ds::getPrimitiveById).collect(Collectors.toList()));
    114         }
    115         return true;
    116118    }
    117119
     
    150152
    151153    @Override
    152     public Icon getDescriptionIcon() {
    153         return null;
    154     }
    155 
    156     @Override
    157154    public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
    158155            Collection<OsmPrimitive> added) {
Note: See TracChangeset for help on using the changeset viewer.