From 18074ebcb4b7f886e446e1760336fdf2f1896b96 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 24 Feb 2012 14:26:31 -0800 Subject: Bug 372550 - [flex-hierarchy] Poor performance when refreshing a view with large arrays (Performance unit test) --- .../debug/tests/viewer/model/PerformanceTests.java | 54 +++++++++++++++++++++- .../eclipe/debug/tests/viewer/model/TestModel.java | 14 ++++++ .../viewer/model/VirtualViewerFilterTests.java | 4 +- .../model/VirtualViewerPerformanceTests.java | 3 +- .../viewer/model/VisibleVirtualItemValidator.java | 2 +- .../model/InternalVirtualTreeModelViewer.java | 39 ++++++++++------ 6 files changed, 95 insertions(+), 21 deletions(-) diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/PerformanceTests.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/PerformanceTests.java index 49643a1b0..7b4cb74d2 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/PerformanceTests.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/PerformanceTests.java @@ -51,11 +51,12 @@ abstract public class PerformanceTests extends TestCase implements ITestModelUpd fShell.setMaximized(true); fShell.setLayout(new FillLayout()); + fVirtualItemValidator = new VisibleVirtualItemValidator(0, Integer.MAX_VALUE); fViewer = createViewer(fDisplay, fShell); fListener = new TestModelUpdatesListener(fViewer, false, false); - fShell.open (); + fShell.open(); } abstract protected IInternalTreeModelViewer createViewer(Display display, Shell shell); @@ -87,6 +88,8 @@ abstract public class PerformanceTests extends TestCase implements ITestModelUpd */ abstract protected int getTestModelDepth(); + protected VisibleVirtualItemValidator fVirtualItemValidator; + public void testRefreshStruct() throws InterruptedException { TestModel model = new TestModel(); model.setRoot( new TestElement(model, "root", new TestElement[0] ) ); @@ -105,7 +108,7 @@ abstract public class PerformanceTests extends TestCase implements ITestModelUpd Performance perf = Performance.getDefault(); PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this)); try { - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 10; i++) { // Update the model model.setAllAppendix(" - pass " + i); @@ -127,6 +130,53 @@ abstract public class PerformanceTests extends TestCase implements ITestModelUpd } } + public void testRefreshStruct2() throws InterruptedException { + TestModel model = new TestModel(); + model.setRoot( new TestElement(model, "root", new TestElement[0] ) ); + model.setElementChildren(TreePath.EMPTY, TestModel.makeMultiLevelElements2(model, new int[] { 2, 3000, 1}, "model.")); + + fViewer.setAutoExpandLevel(2); + // Create the listener + //fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false); + fListener.reset(); + + // Set the input into the view and update the view. + fViewer.setInput(model.getRootElement()); + while (!fListener.isFinished(ALL_UPDATES_COMPLETE)) if (!fDisplay.readAndDispatch ()) Thread.sleep(0); + //model.validateData(fViewer, TreePath.EMPTY); + + fVirtualItemValidator.setVisibleRange(0, 50); + + Performance perf = Performance.getDefault(); + PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this)); + try { + for (int i = 0; i < 100; i++) { + // Update the model + model.setAllAppendix(" - pass " + i); + + TestElement element = model.getRootElement(); + //fListener.reset(TreePath.EMPTY, element, -1, false, false); + fListener.reset(); + + meter.start(); + model.postDelta(new ModelDelta(element, IModelDelta.CONTENT)); + while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) + if (!fDisplay.readAndDispatch ()) Thread.sleep(0); + model.postDelta(new ModelDelta(element, IModelDelta.CONTENT)); + while (!fListener.isFinished(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE)) + if (!fDisplay.readAndDispatch ()) Thread.sleep(0); + meter.stop(); + System.gc(); + } + + meter.commit(); + perf.assertPerformance(meter); + } finally { + meter.dispose(); + } + } + + public void testRefreshStructReplaceElements() throws InterruptedException { TestModel model = new TestModel(); model.setRoot( new TestElement(model, "root", new TestElement[0] ) ); diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java index e497d5837..d2459f849 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java @@ -688,6 +688,20 @@ public class TestModel implements IElementContentProvider, IElementLabelProvider return elements; } + public static TestElement[] makeMultiLevelElements2(TestModel model, int[] levelCounts, String prefix) { + if (levelCounts.length == 0) return new TestElement[0]; + int count = levelCounts[0]; + int[] oldLevelCounts = levelCounts; + levelCounts = new int[levelCounts.length - 1]; + System.arraycopy(oldLevelCounts, 1, levelCounts, 0, levelCounts.length); + TestElement[] elements = new TestElement[count]; + for (int i = 0; i < count; i++) { + String name = prefix + i; + elements[i] = new TestElement(model, name, makeMultiLevelElements2(model, levelCounts, name + ".")); + } + return elements; + } + public static TestModel simpleMultiLevel() { TestModel model = new TestModel(); model.setRoot( new TestElement(model, "root", new TestElement[] { diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VirtualViewerFilterTests.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VirtualViewerFilterTests.java index b53ac539d..2473019ce 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VirtualViewerFilterTests.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VirtualViewerFilterTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Wind River Systems and others. + * Copyright (c) 2011 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -18,7 +18,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; /** - * @since 3.6 + * @since 3.8 */ public class VirtualViewerFilterTests extends FilterTests { diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VirtualViewerPerformanceTests.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VirtualViewerPerformanceTests.java index 7bc589bf7..3f0fd7dca 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VirtualViewerPerformanceTests.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VirtualViewerPerformanceTests.java @@ -13,6 +13,7 @@ package org.eclipe.debug.tests.viewer.model; import org.eclipse.debug.internal.ui.viewers.model.IInternalTreeModelViewer; import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.VirtualTreeModelViewer; +import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; @@ -26,7 +27,7 @@ public class VirtualViewerPerformanceTests extends PerformanceTests { } protected IInternalTreeModelViewer createViewer(Display display, Shell shell) { - return new VirtualTreeModelViewer(fDisplay, 0, new PresentationContext("TestViewer")); + return new VirtualTreeModelViewer(fDisplay, SWT.VIRTUAL, new PresentationContext("TestViewer"), fVirtualItemValidator); } protected int getTestModelDepth() { diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VisibleVirtualItemValidator.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VisibleVirtualItemValidator.java index b2c122440..b23c5dcbd 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VisibleVirtualItemValidator.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/VisibleVirtualItemValidator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Wind River Systems and others. + * Copyright (c) 2011 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalVirtualTreeModelViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalVirtualTreeModelViewer.java index a2c9a9fc9..1fff9e208 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalVirtualTreeModelViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalVirtualTreeModelViewer.java @@ -220,6 +220,7 @@ public class InternalVirtualTreeModelViewer extends Viewer getContentProvider().inputChanged(this, oldInput, input); fItemsMap.clear(); fInput = input; + mapElement(fInput, getTree()); getContentProvider().postInputChanged(this, oldInput , input); fTree.setData(fInput); fTree.setSelection(EMPTY_ITEMS_ARRAY); @@ -564,28 +565,36 @@ public class InternalVirtualTreeModelViewer extends Viewer return fTree; } - for (int i = 0; item != null && i < path.getSegmentCount(); i++) { - Object segment = path.getSegment(i); - item = item.findItem(segment); + List itemsList = (List)fItemsMap.get(path.getLastSegment()); + for (int i = 0; i < itemsList.size(); i++) { + if ( path.equals(getTreePathFromItem((VirtualItem)itemsList.get(i))) ) { + return (VirtualItem)itemsList.get(i); + } } + +// for (int i = 0; item != null && i < path.getSegmentCount(); i++) { +// Object segment = path.getSegment(i); +// item = item.findItem(segment); +// } return item; } static private final VirtualItem[] EMPTY_ITEMS_ARRAY = new VirtualItem[0]; public VirtualItem[] findItems(Object elementOrTreePath) { - if (elementOrTreePath instanceof TreePath) { - VirtualItem item = findItem((TreePath) elementOrTreePath); - return item == null ? EMPTY_ITEMS_ARRAY : new VirtualItem[] { item }; - } else if (getInput().equals(elementOrTreePath)) { - return new VirtualItem[] { getTree() }; + Object element = elementOrTreePath; + if (elementOrTreePath instanceof TreePath) { + TreePath path = (TreePath)elementOrTreePath; + if (path.getSegmentCount() == 0) { + return new VirtualItem[] { getTree() }; + } + element = path.getLastSegment(); + } + List itemsList = (List) fItemsMap.get(element); + if (itemsList == null) { + return EMPTY_ITEMS_ARRAY; } else { - List itemsList = (List) fItemsMap.get(elementOrTreePath); - if (itemsList == null) { - return EMPTY_ITEMS_ARRAY; - } else { - return (VirtualItem[]) itemsList.toArray(new VirtualItem[itemsList.size()]); - } + return (VirtualItem[]) itemsList.toArray(new VirtualItem[itemsList.size()]); } } @@ -1373,7 +1382,7 @@ public class InternalVirtualTreeModelViewer extends Viewer public void autoExpand(TreePath elementPath) { int level = getAutoExpandLevel(); if (level > 0 || level == org.eclipse.debug.internal.ui.viewers.model.provisional.ITreeModelViewer.ALL_LEVELS) { - if (level == org.eclipse.debug.internal.ui.viewers.model.provisional.ITreeModelViewer.ALL_LEVELS || level >= elementPath.getSegmentCount()) { + if (level == org.eclipse.debug.internal.ui.viewers.model.provisional.ITreeModelViewer.ALL_LEVELS || level > elementPath.getSegmentCount()) { expandToLevel(elementPath, 1); } } -- cgit v1.2.3