]> source.dussan.org Git - vaadin-framework.git/commitdiff
#7517 IndexedContainer.addItem() performance improvement, related performance test
authorHenri Sara <henri.sara@itmill.com>
Thu, 1 Sep 2011 12:11:39 +0000 (12:11 +0000)
committerHenri Sara <henri.sara@itmill.com>
Thu, 1 Sep 2011 12:11:39 +0000 (12:11 +0000)
svn changeset:20789/svn branch:6.6

src/com/vaadin/data/util/AbstractInMemoryContainer.java
src/com/vaadin/data/util/IndexedContainer.java
tests/src/com/vaadin/tests/server/container/PerformanceTestIndexedContainer.java [new file with mode: 0644]

index 3a9a0a89877b4817c319656fa3d04728ff37c1ca..3a48d9e0deda6c413e92b8d4cde0b932eaf88516 100644 (file)
@@ -722,7 +722,7 @@ public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITE
                     getAllItemIds().indexOf(previousItemId) + 1, newItemId,
                     item);
         }
-        if (newItem != null) {
+        if (newItem != null && filter) {
             // TODO filter only this item, use fireItemAdded()
             filterAll();
             if (!isFiltered()) {
index 7fbb1e9128c247ff3339224f09b9b338bdab6f8b..2f45def4f13542c7a92ead863738ee38c9ab7d2f 100644 (file)
@@ -106,8 +106,11 @@ public class IndexedContainer extends
         this();
         if (items != null) {
             for (final Iterator<?> i = itemIds.iterator(); i.hasNext();) {
-                this.addItem(i.next());
+                Object itemId = i.next();
+                internalAddItemAtEnd(itemId, new IndexedContainerItem(itemId),
+                        false);
             }
+            filterAll();
         }
     }
 
@@ -246,8 +249,17 @@ public class IndexedContainer extends
      */
     @Override
     public Item addItem(Object itemId) {
-        return internalAddItemAtEnd(itemId, new IndexedContainerItem(itemId),
-                true);
+        Item item = internalAddItemAtEnd(itemId, new IndexedContainerItem(
+                itemId), false);
+        if (!isFiltered()) {
+            // always the last item
+            fireItemAdded(size() - 1, itemId, item);
+        } else if (passesFilters(itemId)) {
+            getFilteredItemIds().add(itemId);
+            // always the last item
+            fireItemAdded(size() - 1, itemId, item);
+        }
+        return item;
     }
 
     /**
diff --git a/tests/src/com/vaadin/tests/server/container/PerformanceTestIndexedContainer.java b/tests/src/com/vaadin/tests/server/container/PerformanceTestIndexedContainer.java
new file mode 100644 (file)
index 0000000..62e6d88
--- /dev/null
@@ -0,0 +1,117 @@
+package com.vaadin.tests.server.container;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.IndexedContainer;
+
+public class PerformanceTestIndexedContainer extends TestCase {
+
+    private static final int REPEATS = 10;
+    private final static int ITEMS = 50000;
+    private static final long ADD_ITEM_FAIL_THRESHOLD = 200;
+    // TODO should improve performance of these methods
+    private static final long ADD_ITEM_AT_FAIL_THRESHOLD = 5000;
+    private static final long ADD_ITEM_AFTER_FAIL_THRESHOLD = 5000;
+    private static final long ADD_ITEM_AFTER_LAST_FAIL_THRESHOLD = 5000;
+    private static final long ADD_ITEMS_CONSTRUCTOR_FAIL_THRESHOLD = 200;
+
+    public void testAddItemPerformance() {
+        Collection<Long> times = new ArrayList<Long>();
+        for (int j = 0; j < REPEATS; ++j) {
+            IndexedContainer c = new IndexedContainer();
+            long start = System.currentTimeMillis();
+            for (int i = 0; i < ITEMS; i++) {
+                c.addItem();
+            }
+            times.add(System.currentTimeMillis() - start);
+        }
+        checkMedian(ITEMS, times, "IndexedContainer.addItem()",
+                ADD_ITEM_FAIL_THRESHOLD);
+    }
+
+    public void testAddItemAtPerformance() {
+        Collection<Long> times = new ArrayList<Long>();
+        for (int j = 0; j < REPEATS; ++j) {
+            IndexedContainer c = new IndexedContainer();
+            long start = System.currentTimeMillis();
+            for (int i = 0; i < ITEMS; i++) {
+                c.addItemAt(0);
+            }
+            times.add(System.currentTimeMillis() - start);
+        }
+        checkMedian(ITEMS, times, "IndexedContainer.addItemAt()",
+                ADD_ITEM_AT_FAIL_THRESHOLD);
+    }
+
+    public void testAddItemAfterPerformance() {
+        Object initialId = "Item0";
+        Collection<Long> times = new ArrayList<Long>();
+        for (int j = 0; j < REPEATS; ++j) {
+            IndexedContainer c = new IndexedContainer();
+            c.addItem(initialId);
+            long start = System.currentTimeMillis();
+            for (int i = 0; i < ITEMS; i++) {
+                c.addItemAfter(initialId);
+            }
+            times.add(System.currentTimeMillis() - start);
+        }
+        checkMedian(ITEMS, times, "IndexedContainer.addItemAfter()",
+                ADD_ITEM_AFTER_FAIL_THRESHOLD);
+    }
+
+    public void testAddItemAfterLastPerformance() {
+        // TODO running with less items because slow otherwise
+        Collection<Long> times = new ArrayList<Long>();
+        for (int j = 0; j < REPEATS; ++j) {
+            IndexedContainer c = new IndexedContainer();
+            c.addItem();
+            long start = System.currentTimeMillis();
+            for (int i = 0; i < ITEMS / 3; i++) {
+                c.addItemAfter(c.lastItemId());
+            }
+            times.add(System.currentTimeMillis() - start);
+        }
+        checkMedian(ITEMS / 3, times, "IndexedContainer.addItemAfter(lastId)",
+                ADD_ITEM_AFTER_LAST_FAIL_THRESHOLD);
+    }
+
+    public void testAddItemsConstructorPerformance() {
+        Collection<Object> items = new ArrayList<Object>(50000);
+        for (int i = 0; i < ITEMS; ++i) {
+            items.add(new Object());
+        }
+
+        SortedSet<Long> times = new TreeSet<Long>();
+        for (int j = 0; j < REPEATS; ++j) {
+            long start = System.currentTimeMillis();
+            new IndexedContainer(items);
+            times.add(System.currentTimeMillis() - start);
+        }
+        checkMedian(ITEMS, times, "IndexedContainer(Collection)",
+                ADD_ITEMS_CONSTRUCTOR_FAIL_THRESHOLD);
+    }
+
+    private void checkMedian(int items, Collection<Long> times,
+            String methodName, long threshold) {
+        long median = median(times);
+        System.out.println(methodName + " timings (ms) for " + items
+                + " items: " + times);
+        Assert.assertTrue(methodName + " too slow, median time " + median
+                + "ms for " + items + " items", median <= threshold);
+    }
+
+    private Long median(Collection<Long> times) {
+        ArrayList<Long> list = new ArrayList<Long>(times);
+        Collections.sort(list);
+        // not exact median in some cases, but good enough
+        return list.get(list.size() / 2);
+    }
+
+}