From 50c52079f8a4e42698200251578ca532cf6510a9 Mon Sep 17 00:00:00 2001 From: marecabo <23156476+marecabo@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:24:55 +0200 Subject: [PATCH] Only parallelize getting activityEndTimes --- .../dynagent/run/DynActivityEngine.java | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/run/DynActivityEngine.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/run/DynActivityEngine.java index cfb0958c0c8..1872d6ff35c 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/run/DynActivityEngine.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/run/DynActivityEngine.java @@ -20,11 +20,13 @@ package org.matsim.contrib.dynagent.run; import java.util.ArrayList; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Objects; +import java.util.Map; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdCollectors; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.dynagent.DynAgent; @@ -56,31 +58,30 @@ public void doSimStep(double time) { dynAgents.addAll(newDynAgents); newDynAgents.clear(); - List agentsToRemove = dynAgents.parallelStream() - .map(agent -> { - - Preconditions.checkState(agent.getState() == State.ACTIVITY); - agent.doSimStep(time); - // ask agents about the current activity end time; - double currentEndTime = agent.getActivityEndTime(); - - if (currentEndTime == Double.POSITIVE_INFINITY) { // agent says: stop simulating me - unregisterAgentAtActivityLocation(agent); - internalInterface.getMobsim().getAgentCounter().decLiving(); - return agent; - } else if (currentEndTime <= time) { // the agent wants to end the activity NOW - unregisterAgentAtActivityLocation(agent); - agent.endActivityAndComputeNextState(time); - internalInterface.arrangeNextAgentState(agent); - return agent; - } - - return null; - }) - .filter(Objects::nonNull) - .toList(); - - dynAgents.removeAll(agentsToRemove); + // computing end times is the heaviest part here and can be parallelized + // Todo: use forkJoinPool and respect globalThreads property + Map, Double> activityEndTimes = dynAgents.parallelStream() + .collect(IdCollectors.toIdMap(Person.class, MobsimAgent::getId, MobsimAgent::getActivityEndTime)); + + Iterator dynAgentIter = dynAgents.iterator(); + while (dynAgentIter.hasNext()) { + DynAgent agent = dynAgentIter.next(); + Preconditions.checkState(agent.getState() == State.ACTIVITY); + agent.doSimStep(time); + // ask agents about the current activity end time; + double currentEndTime = activityEndTimes.get(agent.getId()); + + if (currentEndTime == Double.POSITIVE_INFINITY) { // agent says: stop simulating me + unregisterAgentAtActivityLocation(agent); + internalInterface.getMobsim().getAgentCounter().decLiving(); + dynAgentIter.remove(); + } else if (currentEndTime <= time) { // the agent wants to end the activity NOW + unregisterAgentAtActivityLocation(agent); + agent.endActivityAndComputeNextState(time); + internalInterface.arrangeNextAgentState(agent); + dynAgentIter.remove(); + } + } } @Override