| /******************************************************************************* |
| * Copyright (c) 2014, 2016 Willink Transformations Ltd., University of York 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: |
| * Adolfo Sanchez-Barbudo Herrera (University of York) - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.qvtd.cs2as.compiler.tests; |
| |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.jdt.annotation.NonNull; |
| import org.eclipse.ocl.pivot.internal.resource.StandaloneProjectMap; |
| import org.eclipse.ocl.pivot.utilities.ClassUtil; |
| import org.eclipse.ocl.pivot.utilities.OCL; |
| import org.eclipse.ocl.xtext.completeocl.CompleteOCLStandaloneSetup; |
| import org.eclipse.qvtd.pivot.qvtimperative.ImperativeModel; |
| import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTransformation; |
| import org.eclipse.qvtd.pivot.qvtimperative.evaluation.BasicQVTiExecutor; |
| import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiEnvironmentFactory; |
| import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiIncrementalExecutor; |
| import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiTransformationExecutor; |
| import org.eclipse.qvtd.runtime.evaluation.TransformationExecutor; |
| import org.eclipse.qvtd.runtime.evaluation.Transformer; |
| import org.eclipse.qvtd.xtext.qvtbase.tests.LoadTestCase; |
| import org.eclipse.qvtd.xtext.qvtbase.tests.utilities.TestsXMLUtil; |
| import org.eclipse.qvtd.xtext.qvtimperative.QVTimperativeStandaloneSetup; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| /** |
| * @author asbh500 |
| * |
| * |
| */ |
| public class ExecutionBenchmarks extends LoadTestCase { |
| |
| private static URI TESTS_BASE_URI = URI.createPlatformResourceURI("org.eclipse.qvtd.cs2as.compiler.tests/src/org/eclipse/qvtd/cs2as/compiler/tests/models", true); |
| private static int NUM_OF_EXECUTIONS = 10; |
| |
| protected class MyQVT extends OCL |
| { |
| public MyQVT(@NonNull QVTiEnvironmentFactory environmentFactory) { |
| super(environmentFactory); |
| } |
| |
| public @NonNull BasicQVTiExecutor createEvaluator(@NonNull ImperativeTransformation transformation) { |
| return new QVTiIncrementalExecutor(getEnvironmentFactory(), transformation, QVTiIncrementalExecutor.Mode.LAZY); |
| } |
| |
| public @NonNull TransformationExecutor createEvaluator(@NonNull Class<? extends Transformer> txClass) throws ReflectiveOperationException { |
| return new QVTiTransformationExecutor(getEnvironmentFactory(), txClass); |
| } |
| @Override |
| public @NonNull QVTiEnvironmentFactory getEnvironmentFactory() { |
| return (QVTiEnvironmentFactory) super.getEnvironmentFactory(); |
| } |
| } |
| |
| @Override |
| @Before |
| public void setUp() throws Exception { |
| super.setUp(); |
| QVTimperativeStandaloneSetup.doSetup(); |
| CompleteOCLStandaloneSetup.doSetup(); // To be able to add QVTimperative.ocl validation |
| } |
| |
| protected @NonNull MyQVT createQVT() { |
| return new MyQVT(new QVTiEnvironmentFactory(getProjectMap(), null)); |
| } |
| |
| @Test |
| public void testExample2_Interpreted() throws Exception { |
| |
| |
| Map<String, List<Integer>> results = new LinkedHashMap<String, List<Integer>>(); |
| for (int i = 0; i < NUM_OF_EXECUTIONS; i++){ |
| MyQVT myQVT = createQVT(); |
| ResourceSet resourceSet = myQVT.getResourceSet(); |
| resourceSet.getResource(URI.createURI(example2.classes.ClassesPackage.eNS_URI, true), true); |
| resourceSet.getResource(URI.createURI(example2.classescs.ClassescsPackage.eNS_URI, true), true); |
| resourceSet.getResource(URI.createURI(example2.classes.lookup.EnvironmentPackage.eNS_URI, true), true); |
| |
| URI baseURI = TESTS_BASE_URI.appendSegment("example2"); |
| URI txURI = baseURI.appendSegment("classescs2as.qvtias"); |
| |
| ImperativeTransformation qvtiTransf = getTransformation(myQVT.getMetamodelManager().getASResourceSet(), txURI); |
| assert qvtiTransf != null; |
| trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model1", results); |
| trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model2", results); |
| trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model3", results); |
| trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model4", results); |
| trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model5", results); |
| trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model6", results); |
| trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model7", results); |
| myQVT.dispose(); |
| |
| } |
| |
| |
| processResults("Example2_Interpreted.csv" ,results); |
| } |
| |
| |
| |
| @Test |
| public void testExample2_CG() throws Exception { |
| |
| Map<String, List<Integer>> results = new LinkedHashMap<String, List<Integer>>(); |
| for (int i = 0; i < NUM_OF_EXECUTIONS; i++){ |
| MyQVT myQVT = createQVT(); |
| |
| URI baseURI = TESTS_BASE_URI.appendSegment("example2"); |
| @SuppressWarnings("unchecked") |
| Class<? extends Transformer> txClass = (Class<? extends Transformer>) Class.forName("cg._classescs2as_qvtp_qvtcas.classescs2as_qvtp_qvtcas"); |
| assert txClass != null; |
| trackExample_CG(myQVT, txClass, baseURI, "model1", results); |
| trackExample_CG(myQVT, txClass, baseURI, "model2", results); |
| trackExample_CG(myQVT, txClass, baseURI, "model3", results); |
| trackExample_CG(myQVT, txClass, baseURI, "model4", results); |
| trackExample_CG(myQVT, txClass, baseURI, "model5", results); |
| trackExample_CG(myQVT, txClass, baseURI, "model6", results); |
| trackExample_CG(myQVT, txClass, baseURI, "model7", results); |
| |
| myQVT.dispose(); |
| |
| } |
| |
| processResults("Example2_CG.csv" ,results); |
| } |
| |
| // @Test |
| // public void testExample2_CG_withLookupVisitor() throws Exception { |
| // |
| // Map<String, List<Integer>> results = new LinkedHashMap<String, List<Integer>>(); |
| // |
| // for (int i = 0; i < NUM_OF_EXECUTIONS; i++){ |
| // MyQVT myQVT = createQVT(); |
| // |
| // URI baseURI = TESTS_BASE_URI.appendSegment("example2"); |
| // |
| // Class<? extends TransformationExecutor> txClass = classescs2as_qvtp_qvtias_Manual.class; |
| // Constructor<? extends TransformationExecutor> txConstructor = ClassUtil.nonNullState(txClass.getConstructor(Evaluator.class)); |
| // |
| // trackExample_CG(myQVT, txConstructor, baseURI, "model1", results); |
| // trackExample_CG(myQVT, txConstructor, baseURI, "model2", results); |
| // trackExample_CG(myQVT, txConstructor, baseURI, "model3", results); |
| // trackExample_CG(myQVT, txConstructor, baseURI, "model4", results); |
| // trackExample_CG(myQVT, txConstructor, baseURI, "model5", results); |
| // trackExample_CG(myQVT, txConstructor, baseURI, "model6", results); |
| // trackExample_CG(myQVT, txConstructor, baseURI, "model7", results); |
| // |
| // myQVT.dispose(); |
| // |
| // } |
| // |
| // processResults("Example2_CG_withLookupVisitor.csv" ,results); |
| // } |
| |
| |
| private void trackExample_CG(MyQVT qvt, @NonNull Class<? extends Transformer> txClass, URI baseURI, String modelName, |
| Map<String, List<Integer>> results) throws Exception { |
| |
| long initStamp = System.currentTimeMillis(); |
| executeModelsTX_CG(qvt, txClass, baseURI, modelName); |
| long finalStamp = System.currentTimeMillis(); |
| trackResults(results, modelName, initStamp, finalStamp); |
| System.out.println("Iteration on " +modelName+": " + (finalStamp - initStamp) + " ms"); |
| } |
| |
| private void trackExample_Interpreted(MyQVT qvt, @NonNull ImperativeTransformation tx, URI baseURI, String modelName, |
| Map<String, List<Integer>> results) throws Exception { |
| long initStamp = System.currentTimeMillis(); |
| executeModelsTX_Interpreted(qvt, tx, baseURI, modelName); |
| long finalStamp = System.currentTimeMillis(); |
| trackResults(results, modelName, initStamp, finalStamp); |
| System.out.println("Iteration on " +modelName+": " + (finalStamp - initStamp) + " ms"); |
| } |
| |
| private void trackResults(Map<String, List<Integer>> allResults, String modelName, long initStamp, long finalStamp) { |
| |
| List<Integer> modelResults = allResults.get(modelName); |
| if (modelResults == null) { |
| modelResults = new ArrayList<Integer>(); |
| allResults.put(modelName, modelResults); |
| } |
| modelResults.add((int)(finalStamp - initStamp)); |
| } |
| |
| |
| private void processResults(String fileName, Map<String, List<Integer>> allResults) throws Exception { |
| |
| File file = new File( fileName); |
| FileWriter fWriter = new FileWriter(file); |
| fWriter.write("Model Name,Execution Time,Model Mean\n"); |
| |
| for (String modelName : allResults.keySet()) { |
| List<Integer> modelResults = allResults.get(modelName); |
| if (modelResults != null) { |
| modelResults.remove(0); // We eliminate the first result with the warm-up |
| for (Integer time : modelResults) { |
| fWriter.write(modelName+","+time.toString()+",\n"); |
| } |
| } |
| } |
| |
| fWriter.close(); |
| } |
| |
| |
| @SuppressWarnings("unused") |
| private static float mean(List<Integer> list) { |
| int result = 0; |
| for (Integer value : list) { |
| result += value; |
| } |
| return result / list.size(); |
| } |
| |
| // |
| // Execute the transformation with the interpreter |
| // |
| protected void executeModelsTX_CG(MyQVT qvt, @NonNull Class<? extends Transformer> txClass, URI baseURI, String modelName) throws Exception { |
| |
| TransformationExecutor evaluator = qvt.createEvaluator(txClass); |
| Transformer tx = evaluator.getTransformer(); |
| URI samplesBaseUri = baseURI.appendSegment("samples"); |
| URI csModelURI = samplesBaseUri.appendSegment(String.format("%s_input.xmi", modelName)); |
| URI asModelURI = samplesBaseUri.appendSegment(String.format("%s_output_CG.xmi", modelName)); |
| |
| ResourceSet rSet = qvt.getResourceSet(); |
| Resource inputResource = rSet.getResource(csModelURI, true); |
| tx.addRootObjects("leftCS", ClassUtil.nonNullState(inputResource.getContents())); |
| boolean success = tx.run(); |
| Resource outputResource = rSet.createResource(asModelURI); |
| outputResource.getContents().addAll(tx.getRootEObjects("rightAS")); |
| outputResource.save(TestsXMLUtil.defaultSavingOptions); |
| assertTrue(success); |
| } |
| |
| // |
| // Execute the transformation with the CGed transformation |
| // |
| |
| protected void executeModelsTX_Interpreted(MyQVT qvt, @NonNull ImperativeTransformation tx, URI baseURI, String modelName) throws Exception { |
| |
| URI samplesBaseUri = baseURI.appendSegment("samples"); |
| URI csModelURI = samplesBaseUri.appendSegment(String.format("%s_input.xmi", modelName)); |
| URI asModelURI = samplesBaseUri.appendSegment(String.format("%s_output_Interpreted.xmi", modelName)); |
| |
| BasicQVTiExecutor testEvaluator = qvt.createEvaluator(tx); |
| testEvaluator.saveTransformation(null); |
| testEvaluator.loadModel("leftCS", csModelURI); |
| testEvaluator.createModel("rightAS", asModelURI, null); |
| boolean success = testEvaluator.execute(); |
| testEvaluator.saveModels(TestsXMLUtil.defaultSavingOptions); |
| testEvaluator.dispose(); |
| assertTrue(success); |
| } |
| |
| protected void saveEmptyModel( URI modelURI) throws IOException { |
| |
| ResourceSet rSet = new ResourceSetImpl(); |
| StandaloneProjectMap.getAdapter(rSet); |
| Resource r = rSet.createResource(modelURI); |
| r.save(TestsXMLUtil.defaultSavingOptions); |
| } |
| |
| protected ImperativeTransformation getTransformation(ResourceSet rSet, URI qvtiURI) { |
| |
| Resource resource = rSet.getResource(qvtiURI, true); |
| for (EObject eObject : resource.getContents()) { |
| if (eObject instanceof ImperativeModel) { |
| for (org.eclipse.ocl.pivot.Package pPackage : ((ImperativeModel)eObject).getOwnedPackages()) { |
| for (org.eclipse.ocl.pivot.Class pClass : pPackage.getOwnedClasses()) { |
| if (pClass instanceof ImperativeTransformation) { |
| return (ImperativeTransformation) pClass; |
| } |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| |
| } |