| /******************************************************************************* |
| * Copyright (c) 2000, 2015 IBM Corporation 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 |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * James Blackburn (Broadcom Corp.) - ongoing development |
| *******************************************************************************/ |
| package org.eclipse.core.tests.resources.perf; |
| |
| import java.util.Vector; |
| import junit.framework.Test; |
| import junit.framework.TestSuite; |
| import org.eclipse.core.internal.watson.ElementTree; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.tests.harness.PerformanceTestRunner; |
| import org.eclipse.core.tests.resources.OldCorePerformanceTest; |
| |
| /** |
| * Benchmarks for <code>ElementTree</code>. |
| */ |
| public class BenchElementTree extends OldCorePerformanceTest { |
| static String[] javaLangUnits = {"AbstractMethodError.java", "ArithmeticException.java", "ArrayIndexOutOfBoundsException.java", "ArrayStoreException.java", "Boolean.java", // |
| "Byte.java", "Character.java", "Class.java", "ClassCastException.java", "ClassCircularityError.java", "ClassFormatError.java", "ClassLoader.java", "ClassNotFoundException.java", // |
| "Cloneable.java", "CloneNotSupportedException.java", "Compiler.java", "Double.java", "Error.java", "Exception.java", "ExceptionInInitializerError.java", "Float.java", "FloatingDecimal.java", // |
| "IllegalAccessError.java", "IllegalAccessException.java", "IllegalArgumentException.java", "IllegalMonitorStateException.java", "IllegalStateException.java", "IllegalThreadStateException.java", // |
| "IncompatibleClassChangeError.java", "IndexOutOfBoundsException.java", "InstantiationError.java", "InstantiationException.java", "Integer.java", "InternalError.java", "InterruptedException.java", // |
| "LinkageError.java", "Long.java", "Math.java", "NegativeArraySizeException.java", "NoClassDefFoundError.java", "NoSuchFieldError.java", "NoSuchFieldException.java", "NoSuchMethodError.java", // |
| "NoSuchMethodException.java", "NullPointerException.java", "Number.java", "NumberFormatException.java", "Object.java", "OutOfMemoryError.java", "Process.java", "Runnable.java", // |
| "Runtime.java", "RuntimeException.java", "SecurityException.java", "SecurityManager.java", "Short.java", "StackOverflowError.java", "String.java", "StringBuffer.java", // |
| "StringIndexOutOfBoundsException.java", "System.java", "Thread.java", "ThreadDeath.java", "ThreadGroup.java", "Throwable.java", "UnknownError.java", "UnsatisfiedLinkError.java", // |
| "VerifyError.java", "VirtualMachineError.java", "Void.java"}; |
| |
| static final IPath solution = Path.ROOT.append("solution"); |
| static final IPath project = solution.append("project"); |
| static final IPath folder = project.append("folder"); |
| static final IPath[] files = getFilePaths(); |
| |
| public BenchElementTree() { |
| super(); |
| } |
| |
| public BenchElementTree(String name) { |
| super(name); |
| } |
| |
| /** |
| * Tests the performance of the createElement operation. |
| */ |
| public void testCreateElement() { |
| new PerformanceTestRunner() { |
| @Override |
| protected void test() { |
| createTestTree(false); |
| } |
| }.run(this, 10, 400); |
| } |
| |
| /** |
| * Tests the performance of the deleteElement operation. |
| */ |
| public void benchDeleteElement() { |
| final int repeat = 400; |
| |
| /* create copies of the original tree */ |
| ElementTree[] trees = new ElementTree[repeat]; |
| for (int i = 0; i < repeat; i++) { |
| trees[i] = createTestTree(false); |
| } |
| |
| startBench(); |
| for (int rep = repeat; --rep >= 0;) { |
| for (IPath file : files) { |
| trees[rep].deleteElement(file); |
| } |
| } |
| |
| stopBench("benchDeleteElement", repeat * files.length); |
| } |
| |
| /** |
| * Tests the performance of the getElementData operation. |
| */ |
| public void benchGetElementData() { |
| final int repeat = 500; |
| |
| ElementTree tree = createTestTree(false); |
| |
| startBench(); |
| |
| for (int rep = repeat; --rep >= 0;) { |
| for (IPath file : files) { |
| tree.getElementData(file); |
| } |
| } |
| |
| stopBench("benchGetElementData", repeat * files.length); |
| } |
| |
| /** |
| * Tests the performance of the mergeDeltaChain operation. |
| */ |
| public void benchMergeDeltaChain() { |
| final int repeat = 50; |
| |
| /* create all the test trees */ |
| ElementTree[] bases = new ElementTree[repeat]; |
| ElementTree[][] chains = new ElementTree[repeat][]; |
| for (int i = 0; i < repeat; i++) { |
| bases[i] = createTestTree(true); |
| chains[i] = buildDeltaChain(createTestTree(false)); |
| } |
| startBench(); |
| |
| for (int i = repeat; --i >= 0;) { |
| bases[i].mergeDeltaChain(folder, chains[i]); |
| } |
| |
| stopBench("benchMergeDeltaChain", repeat); |
| } |
| |
| /** |
| * Tests a typical series of ElementTree operations, where |
| * a new delta is generated for each operation. |
| */ |
| public void benchRoutineOperations() { |
| final int repeat = 75; |
| |
| int opCount = 0; |
| startBench(); |
| |
| for (int i = 0; i < repeat; i++) { |
| opCount += doRoutineOperations(); |
| } |
| |
| stopBench("benchRoutineOperations", opCount); |
| } |
| |
| /** |
| * Tests the performance of the setElementData operation. |
| */ |
| public void benchSetElementData() { |
| ElementTree tree = createTestTree(false); |
| Object data = new Object(); |
| |
| startBench(); |
| |
| for (int rep = 500; --rep >= 0;) { |
| for (IPath file : files) { |
| tree.setElementData(file, data); |
| } |
| } |
| |
| stopBench("benchSetElementData", 500 * files.length); |
| } |
| |
| /** |
| * Does several routine operations on the given tree. |
| * Returns an array of all the intermediary element trees. |
| */ |
| private ElementTree[] buildDeltaChain(ElementTree tree) { |
| Vector<ElementTree> trees = new Vector<>(); |
| trees.addElement(tree); |
| |
| int repeat = 1; |
| |
| /* create file elements */ |
| tree = tree.newEmptyDelta(); |
| IPath[] filePaths = getFilePaths(); |
| for (IPath filePath : filePaths) { |
| Object data = filePath.toString(); |
| tree.createElement(filePath, data); |
| |
| tree.immutable(); |
| trees.addElement(tree); |
| tree = tree.newEmptyDelta(); |
| } |
| |
| /* modify the data of all file elements a few times */ |
| for (int i = 0; i < repeat; i++) { |
| Object data = "data" + i; |
| for (IPath filePath : filePaths) { |
| tree.setElementData(filePath, data); |
| |
| tree.immutable(); |
| trees.addElement(tree); |
| tree = tree.newEmptyDelta(); |
| } |
| } |
| |
| /* delete all file elements */ |
| for (IPath filePath : filePaths) { |
| tree.deleteElement(filePath); |
| tree.immutable(); |
| trees.addElement(tree); |
| tree = tree.newEmptyDelta(); |
| } |
| |
| ElementTree[] results = new ElementTree[trees.size()]; |
| trees.copyInto(results); |
| return results; |
| } |
| |
| /** |
| * Creates a test element tree. If withDeltas is true, |
| * a new delta is created after each operation. |
| */ |
| ElementTree createTestTree(boolean withDeltas) { |
| ElementTree tree = new ElementTree(); |
| Object data = new Object(); |
| |
| tree.createElement(solution, data); |
| |
| if (withDeltas) { |
| tree.immutable(); |
| tree = tree.newEmptyDelta(); |
| } |
| tree.createElement(project, data); |
| if (withDeltas) { |
| tree.immutable(); |
| tree = tree.newEmptyDelta(); |
| } |
| tree.createElement(folder, data); |
| |
| for (String javaLangUnit : javaLangUnits) { |
| if (withDeltas) { |
| tree.immutable(); |
| tree = tree.newEmptyDelta(); |
| } |
| IPath file = folder.append(javaLangUnit); |
| tree.createElement(file, data); |
| } |
| return tree; |
| } |
| |
| /** |
| * Tests a typical series of ElementTree operations, where |
| * a new delta is generated for each operation. |
| * Returns the number of basic ElementTree operations performed. |
| */ |
| private int doRoutineOperations() { |
| ElementTree tree = createTestTree(true); |
| int repeat = 1; |
| |
| /* modify the data of all file elements a few times */ |
| for (int i = 0; i < repeat; i++) { |
| Object data = "data" + i; |
| for (IPath file : files) { |
| tree = tree.newEmptyDelta(); |
| tree.setElementData(file, data); |
| tree.immutable(); |
| } |
| } |
| |
| /* delete all file elements */ |
| for (IPath file : files) { |
| tree = tree.newEmptyDelta(); |
| tree.deleteElement(file); |
| tree.immutable(); |
| } |
| |
| return (repeat + 2) * files.length; |
| } |
| |
| static IPath[] getFilePaths() { |
| IPath[] jcuIDs = new IPath[javaLangUnits.length]; |
| for (int i = 0, len = javaLangUnits.length; i < len; ++i) { |
| jcuIDs[i] = folder.append(javaLangUnits[i]); |
| } |
| return jcuIDs; |
| } |
| |
| /** |
| * The environment should be set-up in the main method. |
| */ |
| @Override |
| protected void setUp() throws Exception { |
| //benchmarks don't use the core testing infrastructure |
| } |
| |
| public static Test suite() { |
| TestSuite suite = new TestSuite(BenchElementTree.class.getName()); |
| |
| suite.addTest(new BenchElementTree("benchCreateElement")); |
| suite.addTest(new BenchElementTree("benchDeleteElement")); |
| suite.addTest(new BenchElementTree("benchDeltaLargeTreeFewChanges")); |
| suite.addTest(new BenchElementTree("benchDeltaLargeTreeManyChangesInOneLayer")); |
| suite.addTest(new BenchElementTree("benchDeltaSmallTreeManyChangesInSeperateLayers")); |
| suite.addTest(new BenchElementTree("benchGetElementData")); |
| // suite.addTest(new BenchElementTree("benchMergeDeltaChain")); |
| suite.addTest(new BenchElementTree("benchReverseDeltaLargeTreeFewChanges")); |
| suite.addTest(new BenchElementTree("benchReverseDeltaLargeTreeManyChangesInOneLayer")); |
| suite.addTest(new BenchElementTree("benchReverseDeltaSmallTreeManyChangesInSeperateLayers")); |
| suite.addTest(new BenchElementTree("benchRoutineOperations")); |
| suite.addTest(new BenchElementTree("benchSetElementData")); |
| |
| return suite; |
| } |
| |
| /** |
| * |
| */ |
| @Override |
| protected void tearDown() throws Exception { |
| //ElementTree tests don't use the CoreTest infrastructure |
| } |
| } |