]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Some performance optimization
authorvillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 16 Jun 2014 12:51:48 +0000 (12:51 +0000)
committervillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 16 Jun 2014 12:51:48 +0000 (12:51 +0000)
refs #4765

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@29618 ac1ea38d-2e2b-0410-8846-a27921b304fc

fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/EnumElementsVariableBase.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/EnumSizeVariableBase.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Environment.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Solver.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Variable.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableBase.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/GameResult.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SimulateDurationJob.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperimentBase.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperimentInternal.java

index d80d5dfde22473e22a29efef8d02af47cb8e9174..4ef4da1e11a5443a9257fa0b8ae6afc1b65e3140 100644 (file)
@@ -29,7 +29,7 @@ public class EnumElementsVariableBase extends VariableBase {
        }\r
 \r
        @Override\r
-       public Object evaluate(IEnvironment environment, IExpression[] subscripts) {\r
+       public Object evaluate(IEnvironment environment, IExpression[] subscripts, int constantIndex) {\r
                return result;\r
        }\r
 \r
index 6ed388f0e5bf084bbbb83705d7b861c87738f5af..63db718aae1b8b1d0a85fe38f78043de2dad0258 100644 (file)
@@ -25,7 +25,7 @@ public class EnumSizeVariableBase extends VariableBase {
        }\r
 \r
        @Override\r
-       public Object evaluate(IEnvironment environment, IExpression[] subscripts) {\r
+       public Object evaluate(IEnvironment environment, IExpression[] subscripts, int constantIndex) {\r
                return value;\r
        }       \r
 \r
index 90f84a9b328fe6d2350c07a50828504a4d7605c8..f3a96b8d6a5f99492f1660f51025724e3ec1a665 100644 (file)
@@ -383,6 +383,7 @@ final public class Environment implements IEnvironment, ISystem {
        }\r
 \r
        double[] valueArray;\r
+       int[] valueIndices;\r
        \r
        public void addIndexed(int dimensions[], ArrayList<String> keys, String prefix, int d) {\r
 \r
@@ -462,13 +463,15 @@ final public class Environment implements IEnvironment, ISystem {
                        keyIndexMap.put(key, index);\r
                }\r
                \r
+               valueIndices = new int[keys.size()];\r
+               getValueIndices();\r
+               \r
                return keys.toArray(new String[keys.size()]);\r
                \r
        }\r
+       \r
+       public int[] getValueIndices() {\r
 \r
-       // TODO: this is probably not smart at all, figure out a better way to obtain results\r
-       public double[] getValueArray() {\r
-               \r
                int offset = 0;\r
 \r
                Set<String> used = new HashSet<String>();\r
@@ -477,17 +480,14 @@ final public class Environment implements IEnvironment, ISystem {
                        Variable v = model.assignmentArray[i].target;\r
                        if(!used.add(v.base.name)) continue;\r
                        for(int index=0;index<v.base.dimension();index++)\r
-                               valueArray[offset++] = (Double)getValue(v.base.index(this, null)+index);\r
+                               valueIndices[offset++] = v.base.index(this, null)+index;\r
                }\r
                \r
                for (int i = 0; i < model.derivativeArray.length; i++) {\r
                        Variable v = model.derivativeArray[i].target;\r
                        if(!used.add(v.base.name)) continue;\r
                        for(int index=0;index<v.base.dimension();index++) {\r
-                               Double value = (Double)getValue(v.base.index(this, null)+index);\r
-                               // FIXME: should not be fixed like this\r
-                               if(value == null) value = 0.0;\r
-                               valueArray[offset++] = value;\r
+                               valueIndices[offset++] = v.base.index(this, null)+index;\r
                        }\r
                }\r
                \r
@@ -498,18 +498,73 @@ final public class Environment implements IEnvironment, ISystem {
                        Variable v = model.parameterArray[i].variable;\r
                        if(!used.add(v.base.name)) continue;\r
                        for(int index=0;index<v.base.dimension();index++)\r
-                               valueArray[offset++] = (Double)getValue(v.base.index(this, null)+index);\r
+                               valueIndices[offset++] = v.base.index(this, null)+index;\r
                }\r
 \r
                for(Map.Entry<String,VariableBase> entry : model.copies.entrySet()) {\r
                        VariableBase base = entry.getValue();\r
                        if(!used.add(entry.getKey())) continue;\r
                        for(int index=0;index<base.dimension();index++)\r
-                               valueArray[offset++] = (Double)getValue(base.index(this, null)+index);\r
+                               valueIndices[offset++] = base.index(this, null)+index;\r
+               }\r
+               \r
+               return valueIndices;\r
+               \r
+       }\r
+\r
+       // TODO: this is probably not smart at all, figure out a better way to obtain results\r
+       public double[] getValueArray() {\r
+\r
+               for(int i=0;i<valueArray.length;i++) {\r
+                       Double value = (Double)getValue(valueIndices[i]);\r
+                       // FIXME: should not be fixed like this\r
+                       if(value == null) value = 0.0;\r
+                       valueArray[i] = value;\r
                }\r
                \r
                return valueArray;\r
                \r
+//             int offset = 0;\r
+//\r
+//             Set<String> used = new HashSet<String>();\r
+//\r
+//             for (int i = 0; i < model.assignmentArray.length; i++) {\r
+//                     Variable v = model.assignmentArray[i].target;\r
+//                     if(!used.add(v.base.name)) continue;\r
+//                     for(int index=0;index<v.base.dimension();index++)\r
+//                             valueArray[offset++] = (Double)getValue(v.base.index(this, null)+index);\r
+//             }\r
+//             \r
+//             for (int i = 0; i < model.derivativeArray.length; i++) {\r
+//                     Variable v = model.derivativeArray[i].target;\r
+//                     if(!used.add(v.base.name)) continue;\r
+//                     for(int index=0;index<v.base.dimension();index++) {\r
+//                             Double value = (Double)getValue(v.base.index(this, null)+index);\r
+//                             // FIXME: should not be fixed like this\r
+//                             if(value == null) value = 0.0;\r
+//                             valueArray[offset++] = value;\r
+//                     }\r
+//             }\r
+//             \r
+//             // NOTE: there is room for optimization as parameter values that do not\r
+//             // change should only be obtained once (and parameter values that do\r
+//             // change are (possibly) included in assignments or derivatives)\r
+//             for(int i = 0; i < model.parameterArray.length; i++) {\r
+//                     Variable v = model.parameterArray[i].variable;\r
+//                     if(!used.add(v.base.name)) continue;\r
+//                     for(int index=0;index<v.base.dimension();index++)\r
+//                             valueArray[offset++] = (Double)getValue(v.base.index(this, null)+index);\r
+//             }\r
+//\r
+//             for(Map.Entry<String,VariableBase> entry : model.copies.entrySet()) {\r
+//                     VariableBase base = entry.getValue();\r
+//                     if(!used.add(entry.getKey())) continue;\r
+//                     for(int index=0;index<base.dimension();index++)\r
+//                             valueArray[offset++] = (Double)getValue(base.index(this, null)+index);\r
+//             }\r
+//             \r
+//             return valueArray;\r
+               \r
        }\r
 \r
        @Override\r
index 26dd674e49cca1e15790e2f3dceb1539d2663db1..7fe131d899bb3f2768c6876d2a73f880c2463c0d 100644 (file)
@@ -28,7 +28,7 @@ import fi.semantum.sysdyn.solver.parser.SimpleNode;
 \r
 public class Solver {\r
 \r
-       private static final boolean PRINT_EXCEPTIONS = true;   \r
+       private static final boolean PRINT_EXCEPTIONS = false;  \r
        private static final int STACK_SIZE = 1000;\r
 \r
        private Model model;\r
index e72ececdf80b4bacb2ff864cef8d9b13e067538a..9335f68f77a6fcaa97490583747a0e50f60e3974 100644 (file)
@@ -184,10 +184,17 @@ public class Variable implements IExpression {
                }\r
        }\r
        \r
+       // -2 == undefined\r
+       // -1 == not constant\r
+       public int constantIndex = -2;\r
+       \r
        @Override\r
        public Object evaluate(IEnvironment environment) {\r
-               Object result = base.evaluate(environment, subscripts);\r
-               return result;\r
+               \r
+               if(constantIndex == -2) constantIndex = base.getConstantIndex(environment, subscripts);\r
+               \r
+               return base.evaluate(environment, subscripts, constantIndex);\r
+               \r
        }\r
 \r
        \r
index 0e55bf979a06c72363e415053aa5cd228fc8dd15..842cb93a3332b7d6843726b55d6f38468e310eac 100644 (file)
@@ -159,7 +159,56 @@ public class VariableBase {
                \r
        }\r
        \r
-       public Object evaluate(IEnvironment environment, IExpression[] subscripts) {\r
+       public int getConstantIndex(IEnvironment environment, IExpression[] subscripts) {\r
+\r
+               if(isStoredAsArray()) {\r
+                       return -1;\r
+               } else {\r
+                       \r
+                       if(dimension() > 1) {\r
+                               \r
+                               if(subscripts != null) {\r
+                                       \r
+                                       Array[] sub = SolverUtils.parseSubscripts(environment, subscripts);\r
+                                       if(!SolverUtils.isSlice(sub) && areSubscriptsConstant(subscripts)) return index(environment, subscripts);\r
+                                       \r
+                               }\r
+                               \r
+                               return -1;\r
+                               \r
+                       }\r
+                       \r
+                       Object result = environment.getNamedValue(name);\r
+                       if(result != null) return -1;\r
+                       \r
+                       if(!areSubscriptsConstant(subscripts)) return -1;\r
+                       \r
+                       return index(environment, subscripts);\r
+                       \r
+               }\r
+               \r
+       }\r
+       \r
+       boolean areSubscriptsConstant(IExpression[] subscripts) {\r
+               if(subscripts == null) return true;\r
+               for(IExpression e : subscripts) {\r
+                       if(!(e instanceof Constant)) return false;\r
+               }\r
+               return true;\r
+       }\r
+       \r
+       public Object evaluate(IEnvironment environment, IExpression[] subscripts, int constantIndex) {\r
+               \r
+               if(constantIndex >= 0 && environment instanceof Environment) {\r
+                       Double result = (Double)environment.getValue(constantIndex);\r
+                       if(result == null)\r
+                               throw new UnassignedVariableException("No value for " + name);\r
+                       if(SolverUtils.isArray(dimensions) && subscripts == null) {\r
+                               return new Array().addElement(result);\r
+                       } else {\r
+                               return result;\r
+                       }\r
+               }\r
                \r
                if(isStoredAsArray()) {\r
                        \r
index dc08d760c639b26df3ed01166bfaf9cd95d0e2a1..8997ca0742ec3f98535599b0c9357dd7eea7d7f1 100644 (file)
@@ -1,7 +1,7 @@
 package org.simantics.sysdyn.manager;\r
 \r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
+import gnu.trove.list.array.TDoubleArrayList;\r
+import gnu.trove.map.hash.THashMap;\r
 \r
 import org.simantics.modelica.data.DataSet;\r
 import org.simantics.modelica.data.SimulationResult;\r
@@ -13,30 +13,18 @@ import org.simantics.modelica.data.SimulationResult;
  */\r
 public class GameResult extends SimulationResult {\r
        \r
-       private final SysdynGameExperimentBase base;\r
-\r
-       public GameResult(SysdynGameExperimentBase sysdynGameExperiment, HashMap<String, ArrayList<Double>> results, String[] subscription) {\r
+       public GameResult(SysdynGameExperimentBase sysdynGameExperiment, THashMap<String, TDoubleArrayList> results, String[] subscription) {\r
                \r
-               base = sysdynGameExperiment;\r
                // Get times\r
-               ArrayList<Double> timeList = results.get("time");\r
-               double[] times = new double[timeList.size()];\r
-               for(int i = 0; i < timeList.size(); i++) {\r
-                       times[i] = timeList.get(i);\r
-               }\r
+               TDoubleArrayList timeList = results.get("time");\r
+               double[] times = timeList.toArray();\r
                \r
                String name;\r
-               double[] values;\r
-               ArrayList<Double> valueList;\r
                for(int k = 0; k < subscription.length; k++) {\r
                        name = subscription[k];\r
-                       values = new double[timeList.size()];\r
-                       valueList = results.get(name);\r
+                       TDoubleArrayList valueList = results.get(name);\r
                        if(valueList.size() ==  timeList.size()) {\r
-                               for(int i = 0; i < valueList.size(); i++) {\r
-                                       values[i] = valueList.get(i);\r
-                               }\r
-                               this.variables.add(new DataSet(name, times, values));\r
+                               this.variables.add(new DataSet(name, times, valueList.toArray()));\r
                        } else {\r
                                System.err.println("wrong amount of values " + name);\r
                        }\r
index 0f1832843203d293c6c37741c7b53fd1cd5b834d..9ff49128954f234000755354b12e48a9b084cfe8 100644 (file)
@@ -31,6 +31,8 @@ class SimulateDurationJob extends Job {
                if(base == null || base.getState() != ExperimentState.STOPPED)\r
                        return Status.OK_STATUS;\r
 \r
+               long start = System.nanoTime();\r
+               \r
                base.changeState(ExperimentState.RUNNING);\r
                int nSteps = (int)(duration / base.stepLength); \r
                int work = 1 + nSteps * 3 + 2; // initialization + number of steps * number of phases per step + set result + call result listeners \r
@@ -90,6 +92,10 @@ class SimulateDurationJob extends Job {
                        e.printStackTrace();\r
                        System.err.println("SysdynGameExperiment simulateDuration failed: \n\t" + e.getMessage());\r
                }\r
+               \r
+               long end = System.nanoTime();\r
+               System.err.println("simulate duration took " + 1e-6*(end-start) + "ms.");\r
+\r
                return Status.OK_STATUS;\r
                \r
        }\r
index d3f8f19f8080f297b55aaa6fc4273d9752824596..6d8d4a927b865daae22257b8491891ca3c880388 100644 (file)
  *******************************************************************************/\r
 package org.simantics.sysdyn.manager;\r
 \r
+import gnu.trove.list.array.TDoubleArrayList;\r
+import gnu.trove.map.hash.THashMap;\r
+\r
 import java.io.File;\r
 import java.io.FileInputStream;\r
 import java.io.FileNotFoundException;\r
 import java.io.FileOutputStream;\r
 import java.io.IOException;\r
 import java.lang.reflect.Field;\r
-import java.util.ArrayList;\r
 import java.util.HashMap;\r
 \r
 import org.eclipse.core.runtime.IProgressMonitor;\r
 import org.eclipse.core.runtime.NullProgressMonitor;\r
 import org.simantics.Simantics;\r
 import org.simantics.databoard.Bindings;\r
-import org.simantics.db.AsyncReadGraph;\r
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.Session;\r
@@ -35,7 +36,6 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.util.Layer0Utils;\r
 import org.simantics.db.layer0.variable.Variable;\r
 import org.simantics.db.layer0.variable.Variables;\r
-import org.simantics.db.procedure.AsyncListener;\r
 import org.simantics.db.request.Read;\r
 import org.simantics.fmu.FMUControlJNI;\r
 import org.simantics.fmu.FMUJNIException;\r
@@ -43,12 +43,10 @@ import org.simantics.modelica.IModelicaMonitor;
 import org.simantics.modelica.ModelicaManager;\r
 import org.simantics.modelica.SimulationLocation;\r
 import org.simantics.modeling.PartialIC;\r
-import org.simantics.simulation.experiment.ExperimentState;\r
 import org.simantics.sysdyn.SysdynResource;\r
 import org.simantics.sysdyn.simulation.SimulationJob.HeadlessModelicaMonitor;\r
 import org.simantics.sysdyn.solver.ISolver;\r
 import org.simantics.sysdyn.solver.ModelicaSolver;\r
-import org.simantics.utils.datastructures.Quad;\r
 \r
 /**\r
  * Game experiment\r
@@ -79,7 +77,7 @@ public class SysdynGameExperiment extends SysdynGameExperimentBase {
                if(control == null)\r
                        control = new FMUControlJNI();\r
                \r
-               results = new HashMap<String, ArrayList<Double>>();\r
+               results = new THashMap<String, TDoubleArrayList>();\r
                \r
        }\r
        \r
index 91f8e118e80137bd96a7b83db09286e16380d459..421e75d26325f13f4dbd6ead3bbd04a41ca7e07d 100644 (file)
@@ -11,7 +11,9 @@
  *******************************************************************************/\r
 package org.simantics.sysdyn.manager;\r
 \r
-import java.util.ArrayList;\r
+import gnu.trove.list.array.TDoubleArrayList;\r
+import gnu.trove.map.hash.THashMap;\r
+\r
 import java.util.HashMap;\r
 \r
 import org.eclipse.core.runtime.IProgressMonitor;\r
@@ -43,7 +45,7 @@ abstract public class SysdynGameExperimentBase extends OldSysdynExperiment {
        protected HashMap<String, Integer> subscriptionIndexes;\r
        protected double[] currentValues; // Current values from FMU. Updated with updateSubscriptions\r
        \r
-       HashMap<String, ArrayList<Double>> results;\r
+       THashMap<String, TDoubleArrayList> results;\r
 \r
        protected String[] subscription;\r
        \r
@@ -92,8 +94,6 @@ abstract public class SysdynGameExperimentBase extends OldSysdynExperiment {
 \r
        public void setSubscribedResults(IProgressMonitor monitor, double time) throws FMUJNIException {\r
 \r
-//             System.err.println("setSubscribedResults " + time);\r
-               \r
                monitor.subTask("Get results (time = " + time + ")");\r
                currentValues = getSolver().getSubscribedResults(currentValues);\r
                monitor.worked(1);\r
@@ -110,9 +110,9 @@ abstract public class SysdynGameExperimentBase extends OldSysdynExperiment {
        private double lastResultTime = Double.NaN;\r
 \r
        public void setResults(double time, String key, Double value) {\r
-               ArrayList<Double> list = results.get(key);\r
+               TDoubleArrayList list = results.get(key);\r
                if(list == null) {\r
-                       list = new ArrayList<Double>();\r
+                       list = new TDoubleArrayList();\r
                        results.put(key, list);\r
                }\r
                if(time == lastResultTime) {\r
index a3864dfe06b1f4f3c7c70667aec7c5e52341674f..1dfc9a8d676ca7af19de84c2b5fd438386be6c37 100644 (file)
  *******************************************************************************/\r
 package org.simantics.sysdyn.manager;\r
 \r
+import gnu.trove.list.array.TDoubleArrayList;\r
+import gnu.trove.map.hash.THashMap;\r
+\r
 import java.io.IOException;\r
-import java.util.ArrayList;\r
 import java.util.HashMap;\r
 \r
 import org.eclipse.core.runtime.IProgressMonitor;\r
@@ -55,7 +57,7 @@ public class SysdynGameExperimentInternal extends SysdynGameExperimentBase {
                \r
                super.init(g);\r
                \r
-               results = new HashMap<String, ArrayList<Double>>();\r
+               results = new THashMap<String, TDoubleArrayList>();\r
 \r
                solver = new InternalSolver(this, sysdynModel, true, new ISolverMonitor() {\r
                        \r