Skip to content

Commit b07736d

Browse files
author
lindos
committed
Minor performance improvements of the simulator module.
1 parent e9c25a5 commit b07736d

File tree

10 files changed

+60
-83
lines changed

10 files changed

+60
-83
lines changed

JSimpleSim/src/org/simplesim/examples/gameoflife/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public static void main(String[] args) {
2222
final Model model=new Model(GRID_DX,GRID_DY);
2323
model.createCells(LIFE_PROBABILITY);
2424
model.connectCells();
25-
final View view=new View("JSimpleSim exmaple: Conway's Game of Life",GRID_DX,GRID_DY);
25+
final View view=new View("JSimpleSim exmaple: Conway's Game of Life",GRID_DX,GRID_DY,model);
2626
final MessageForwardingStrategy mfs=new DirectMessageForwarding();
2727
final Simulator simulator=new SequentialTSSimulator(model,mfs);
2828
// final Simulator simulator=new ConcurrentTSSimulator(model,mfs);

JSimpleSim/src/org/simplesim/examples/gameoflife/View.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222
public class View extends JFrame implements Listener<Simulator> {
2323

2424
private static final int CELL_SIZE=4;
25+
26+
final Model model;
2527

26-
public View(String title, int width, int height) {
28+
public View(String title, int width, int height, Model m) {
2729
super(title);
30+
model=m;
2831
final Dimension size=new Dimension(CELL_SIZE*width,CELL_SIZE*height);
2932
setPreferredSize(size);
3033
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
@@ -41,7 +44,7 @@ public void notifyListener(Time unused,Simulator source) {
4144
// Get a new graphics context every time through the loop
4245
// to make sure the strategy is validated
4346
final Graphics g=bs.getDrawGraphics();
44-
for (Agent cell : source.getCurrentEventList()) {
47+
for (Agent cell : model.listAllAgents(false)) {
4548
final CellState cs=((Cell) cell).getState();
4649
if (cs.isAlive()) g.setColor(Color.YELLOW);
4750
else g.setColor(Color.BLUE);

JSimpleSim/src/org/simplesim/model/BasicAgent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ public static final ChangeRequest pollModelChangeRequest() {
314314
* @param toggle the status of the simulation, {@code true} means simulation is
315315
* running
316316
*/
317-
public static final void toggleSimulationIsRunning(boolean toggle) {
317+
public static final void setSimulationIsRunning(boolean toggle) {
318318
simulationIsRunning = toggle;
319319
}
320320

JSimpleSim/src/org/simplesim/simulator/BasicSimulator.java

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@
1010
*/
1111
package org.simplesim.simulator;
1212

13-
import java.util.List;
14-
1513
import org.simplesim.core.instrumentation.Listener;
1614
import org.simplesim.core.instrumentation.ListenerSupport;
1715
import org.simplesim.core.messaging.MessageForwardingStrategy;
1816
import org.simplesim.core.scheduling.EventQueue;
1917
import org.simplesim.core.scheduling.Time;
18+
import org.simplesim.model.Agent;
2019
import org.simplesim.model.BasicDomain;
2120
import org.simplesim.model.Domain;
22-
import org.simplesim.model.Agent;
2321

2422
/**
2523
* Implements the core functionality of a simulator.
@@ -31,7 +29,7 @@ public abstract class BasicSimulator implements Simulator {
3129
private final Domain rootDomain;
3230

3331
// current simulation time
34-
private Time simTime=Time.ZERO;
32+
private Time simTime = Time.ZERO;
3533

3634
// the global event queue of the simulation
3735
private final EventQueue<Agent> geq;
@@ -40,10 +38,7 @@ public abstract class BasicSimulator implements Simulator {
4038
private final MessageForwardingStrategy mfs;
4139

4240
// listeners to notify after all agents of a cycle have been processed
43-
private final ListenerSupport<Simulator> eventsProcessedListeners=new ListenerSupport<>();
44-
45-
// list of agents processed in current simulation cycle
46-
private List<Agent> currentEventList;
41+
private final ListenerSupport<Simulator> eventsProcessedListeners = new ListenerSupport<>();
4742

4843
/**
4944
* Constructs a new simulator with given model, queue implementation and
@@ -54,42 +49,38 @@ public abstract class BasicSimulator implements Simulator {
5449
* @param forwarding the strategy to use for message forwarding
5550
*/
5651
public BasicSimulator(BasicDomain root, EventQueue<Agent> queue, MessageForwardingStrategy forwarding) {
57-
rootDomain=root;
58-
geq=queue;
59-
mfs=forwarding;
52+
rootDomain = root;
53+
geq = queue;
54+
mfs = forwarding;
6055
}
6156

62-
/**
63-
* Starts a simulation run
64-
*
65-
* @param stop simulation time when the simulation should stop
66-
*
67-
* @exception Simulator.InvalidSimulatorStateException if there is an error during
68-
* simulation
69-
*/
70-
@Override
71-
public abstract void runSimulation(Time stop);
72-
7357
/**
7458
* Builds the global event queue by querying the local event queues of all
7559
* agents within the root model
7660
*/
7761
protected void initGlobalEventQueue() {
7862
for (Agent agent : getRootDomain().listAllAgents(true)) {
79-
final Time tone=agent.getTimeOfNextEvent();
80-
if (tone==null)
81-
throw new Simulator.InvalidSimulatorStateException("Local event queue empty in agent "+agent.getFullName());
63+
final Time tone = agent.getTimeOfNextEvent();
64+
if (tone == null)
65+
throw new Simulator.InvalidSimulatorStateException(
66+
"Local event queue empty in agent " + agent.getFullName());
8267
getGlobalEventQueue().enqueue(agent,tone);
8368
}
8469
}
8570

8671
@Override
87-
public Domain getRootDomain() { return rootDomain; }
72+
public Domain getRootDomain() {
73+
return rootDomain;
74+
}
8875

8976
@Override
90-
public Time getSimulationTime() { return simTime; }
77+
public Time getSimulationTime() {
78+
return simTime;
79+
}
9180

92-
protected void setSimulationTime(Time time) { simTime=time; }
81+
protected void setSimulationTime(Time time) {
82+
simTime = time;
83+
}
9384

9485
@Override
9586
public void registerEventsProcessedListener(Listener<Simulator> listener) {
@@ -105,13 +96,12 @@ protected void hookEventsProcessed() {
10596
eventsProcessedListeners.notifyListeners(this);
10697
}
10798

108-
protected MessageForwardingStrategy getMessageForwardingStrategy() { return mfs; }
109-
110-
protected EventQueue<Agent> getGlobalEventQueue() { return geq; }
111-
112-
@Override
113-
public List<Agent> getCurrentEventList() { return currentEventList; }
99+
protected MessageForwardingStrategy getMessageForwardingStrategy() {
100+
return mfs;
101+
}
114102

115-
protected void setCurrentEventList(List<Agent> list) { currentEventList=list; }
103+
protected EventQueue<Agent> getGlobalEventQueue() {
104+
return geq;
105+
}
116106

117107
}

JSimpleSim/src/org/simplesim/simulator/ConcurrentDESimulator.java

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,7 @@ public ConcurrentDESimulator(BasicDomain root) {
5555
super(root);
5656
}
5757

58-
/*
59-
* (non-Javadoc)
60-
*
61-
* @see
62-
* org.simplesim.simulator.SequentialDESimulator#runSimulation(org.simplesim.
63-
* core.scheduling.Time)
64-
*/
58+
6559
@Override
6660
public void runSimulation(Time stop) {
6761
initGlobalEventQueue();
@@ -70,16 +64,16 @@ public void runSimulation(Time stop) {
7064
final ExecutorService executor=Executors.newWorkStealingPool();
7165
final List<Future<Time>> futures=new ArrayList<>();
7266
while (getSimulationTime().compareTo(stop)<0) {
73-
BasicAgent.toggleSimulationIsRunning(true);
67+
BasicAgent.setSimulationIsRunning(true);
7468
// part I: process all current events by calling the agents' doEvent method
7569
// and enqueue the next events of the agents
76-
setCurrentEventList(getGlobalEventQueue().dequeueAll());
70+
List<Agent> cel=getGlobalEventQueue().dequeueAll(); // cel=current event list
7771
// start multi-threaded execution
78-
for (Agent agent : getCurrentEventList())
72+
for (Agent agent : cel)
7973
futures.add(executor.submit(() -> agent.doEventSim(getSimulationTime())));
8074
// join threads again and collect results
8175
for (int index=0; index<futures.size(); index++) try {
82-
final Agent agent=getCurrentEventList().get(index);
76+
final Agent agent=cel.get(index);
8377
final Time tone=futures.get(index).get();
8478
if (tone==null) throw new Simulator.InvalidSimulatorStateException(
8579
"Local event queue is empty in agent "+agent.getFullName());
@@ -91,8 +85,8 @@ public void runSimulation(Time stop) {
9185
exception.printStackTrace();
9286
}
9387
// part II: do the message forwarding
94-
getMessageForwardingStrategy().forwardMessages(getCurrentEventList());
95-
BasicAgent.toggleSimulationIsRunning(false);
88+
getMessageForwardingStrategy().forwardMessages(cel);
89+
BasicAgent.setSimulationIsRunning(false);
9690
futures.clear(); // free futures again
9791
hookEventsProcessed();
9892
setSimulationTime(getGlobalEventQueue().getMin());

JSimpleSim/src/org/simplesim/simulator/ConcurrentTSSimulator.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,16 @@ public ConcurrentTSSimulator(BasicDomain root) {
5353

5454
@Override
5555
public void runSimulation(Time stop) {
56-
setCurrentEventList(getRootDomain().listAllAgents(true));
57-
// used a variable thread pool with a maximum of as many worker threads as cpu
58-
// cores
56+
final List<Agent> cel=getRootDomain().listAllAgents(true); // cel=current event list
57+
// used a variable thread pool with a maximum of as many worker threads as cpu cores
5958
final ExecutorService executor=Executors.newWorkStealingPool();
6059
final List<Future<?>> futures=new ArrayList<>();
6160
setSimulationTime(Time.ZERO);
6261
while (getSimulationTime().compareTo(stop)<0) {
63-
BasicAgent.toggleSimulationIsRunning(true);
62+
BasicAgent.setSimulationIsRunning(true);
6463
// part I: process all current events by calling the agents' doEvent method
6564
// in time step, iterate over ALL agents, ignore time of next event
66-
for (Agent agent : getCurrentEventList())
65+
for (Agent agent : cel)
6766
futures.add(executor.submit(() -> agent.doEventSim(getSimulationTime())));
6867
// wait until all threads have finished
6968
try {
@@ -72,8 +71,8 @@ public void runSimulation(Time stop) {
7271
exception.printStackTrace();
7372
}
7473
// part II: do the message forwarding
75-
getMessageForwardingStrategy().forwardMessages(getCurrentEventList());
76-
BasicAgent.toggleSimulationIsRunning(false);
74+
getMessageForwardingStrategy().forwardMessages(cel);
75+
BasicAgent.setSimulationIsRunning(false);
7776
futures.clear();
7877
hookEventsProcessed();
7978
// part III: add the time step

JSimpleSim/src/org/simplesim/simulator/DynamicDecorator.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@
55
*/
66
package org.simplesim.simulator;
77

8-
import java.util.List;
9-
108
import org.simplesim.core.dynamic.ChangeRequest;
119
import org.simplesim.core.instrumentation.Listener;
1210
import org.simplesim.core.scheduling.Time;
13-
import org.simplesim.model.Agent;
1411
import org.simplesim.model.BasicAgent;
1512
import org.simplesim.model.Domain;
1613

@@ -40,7 +37,7 @@ public final class DynamicDecorator implements Simulator {
4037
public DynamicDecorator(Simulator value) {
4138
simulator=value;
4239
// The change listener is notified after a simulation loop. It does not need any time or object info
43-
simulator.registerEventsProcessedListener((time, sim) -> doModelChanges());
40+
simulator.registerEventsProcessedListener((_, _) -> doModelChanges());
4441
}
4542

4643
/**
@@ -64,9 +61,6 @@ private void doModelChanges() {
6461
@Override
6562
public Time getSimulationTime() { return simulator.getSimulationTime(); }
6663

67-
@Override
68-
public List<Agent> getCurrentEventList() { return simulator.getCurrentEventList(); }
69-
7064
@Override
7165
public void registerEventsProcessedListener(Listener<Simulator> listener) {
7266
simulator.registerEventsProcessedListener(listener);

JSimpleSim/src/org/simplesim/simulator/SequentialDESimulator.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
*/
1111
package org.simplesim.simulator;
1212

13+
import java.util.List;
14+
1315
import org.simplesim.core.messaging.MessageForwardingStrategy;
1416
import org.simplesim.core.messaging.RecursiveMessageForwarding;
1517
import org.simplesim.core.scheduling.EventQueue;
@@ -67,12 +69,12 @@ public void runSimulation(Time stop) {
6769
initGlobalEventQueue();
6870
setSimulationTime(getGlobalEventQueue().getMin());
6971
while (getSimulationTime().compareTo(stop)<0) {
70-
BasicAgent.toggleSimulationIsRunning(true);
72+
BasicAgent.setSimulationIsRunning(true);
7173
// part I: process all current events by calling the agents' doEvent method
7274
// and enqueue the next events of the agents
73-
setCurrentEventList(getGlobalEventQueue().dequeueAll());
75+
List<Agent> cel=getGlobalEventQueue().dequeueAll(); // cel=current event list
7476
// System.out.println("Number of concurrent events: "+list.size());
75-
for (Agent agent : getCurrentEventList()) {
77+
for (Agent agent : cel) {
7678
final Time tone=agent.doEventSim(getSimulationTime());
7779
if (tone==null) throw new Simulator.InvalidSimulatorStateException(
7880
"Local event queue is empty in agent "+agent.getFullName());
@@ -82,8 +84,8 @@ public void runSimulation(Time stop) {
8284
getGlobalEventQueue().enqueue(agent,tone);
8385
}
8486
// part II: do the message forwarding
85-
getMessageForwardingStrategy().forwardMessages(getCurrentEventList());
86-
BasicAgent.toggleSimulationIsRunning(false);
87+
getMessageForwardingStrategy().forwardMessages(cel);
88+
BasicAgent.setSimulationIsRunning(false);
8789
hookEventsProcessed();
8890
setSimulationTime(getGlobalEventQueue().getMin());
8991
}

JSimpleSim/src/org/simplesim/simulator/SequentialTSSimulator.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
*/
1111
package org.simplesim.simulator;
1212

13+
import java.util.List;
14+
1315
import org.simplesim.core.messaging.MessageForwardingStrategy;
1416
import org.simplesim.core.messaging.RecursiveMessageForwarding;
1517
import org.simplesim.core.scheduling.Time;
@@ -49,21 +51,19 @@ public SequentialTSSimulator(BasicDomain root) {
4951

5052
@Override
5153
public void runSimulation(Time stop) {
52-
// list of all agents processed in the last event cycle
53-
setCurrentEventList(getRootDomain().listAllAgents(true));
54+
final List<Agent> cel=getRootDomain().listAllAgents(true); // cel=current event list
5455
setSimulationTime(Time.ZERO);
5556
while (getSimulationTime().compareTo(stop)<0) {
56-
BasicAgent.toggleSimulationIsRunning(true);
57+
BasicAgent.setSimulationIsRunning(true);
5758
// part I: process all current events by calling the agents' doEvent method
5859
// in time step, iterate over ALL agents, ignore time of next event
59-
for (Agent agent : getCurrentEventList()) agent.doEventSim(getSimulationTime());
60+
for (Agent agent : cel) agent.doEventSim(getSimulationTime());
6061
// part II: do the message forwarding
61-
getMessageForwardingStrategy().forwardMessages(getCurrentEventList());
62-
BasicAgent.toggleSimulationIsRunning(false);
62+
getMessageForwardingStrategy().forwardMessages(cel);
63+
BasicAgent.setSimulationIsRunning(false);
6364
hookEventsProcessed();
6465
// part III: add the time step
6566
setSimulationTime(getSimulationTime().add(getTimeStep()));
66-
// System.out.println("Simulation time is "+getSimulationTime().toString());
6767
}
6868
}
6969

JSimpleSim/src/org/simplesim/simulator/Simulator.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@
66
*/
77
package org.simplesim.simulator;
88

9-
import java.util.List;
10-
119
import org.simplesim.core.instrumentation.Listener;
1210
import org.simplesim.core.scheduling.Time;
13-
import org.simplesim.model.Agent;
1411
import org.simplesim.model.Domain;
1512

1613
/**
@@ -47,8 +44,6 @@ public InvalidSimulatorStateException(String message) {
4744

4845
Time getSimulationTime();
4946

50-
List<Agent> getCurrentEventList();
51-
5247
/**
5348
* Registers an {@code EventsProcessedListener} to be called after each
5449
* simulation cycle.

0 commit comments

Comments
 (0)