The Wake/Sleep-Model is a design pattern used to increase overall performance with objects that conditionally process data. It defines two states „awake“ and „asleep“ that object can be in. As long as the object is „awake“ it will process data. If the object is „asleep“ it will not process data and has to be „waken up“ by external means typically a function „wake“.
Consider following situation:
- Java
public class Data
{
private List<String> list = new ArrayList<>();
public void add(String entry)
{
this.list.add(entry);
}
public String get(int index)
{
return this.list.get(index);
}
public String contains(String entry)
{
return this.list.contains(entry);
}
public int size()
{
return this.list.size();
}
}
public class Processor
{
private Data data = new Data();
public Data getData()
{
return this.data;
}
public void tick()
{
if(this.data.contains("Test")) return;
int index = -1;
for(int i = 0; i < this.data.size() - 1; i++)
{
if(this.list.get(i).equals("Test"))
{
index = i;
break;
}
}
// Do something else
}
}
public static void main(String[] args)
{
Processor processor = new Processor();
while(true)
{
processor.tick();
// Do something else
}
}
The function „tick“ gets called every cycle of the loop. However the time that a single cycle may take is strictly limited for example because the cycle is a game update and taking too much time would result in lags. Also we assume that the Data of the processor is changed somewhere during the cycles and that the „contains“ function takes fairly long.
If we now also assume that hundreds or thousands of these Processor Objects were created and are updated during the cycle we can imagine that it will start to have quite an impact on the cycle duration.
This situation is not as unrealistic as it might seem. It frequently happens in games with processing maschines like furnaces. The furnace has an inventory which represents our Data class. it also gets updated with every game tick. If we ask every update if the input has items and the output has enough space we unneccessarly slow down the game tick.
Instead we could check the Data object once and if the check fails we see our expectation of the Data object as unreachable. Due to this we stop doing heavy checks and instead put the object into „sleep“ mode and just check if the object is „awake“ or „asleep“. This can be a simple boolean member. Because we now don’t process any other data any more we require an external impulse to „wake“ the object. This impulse usually comes from the Data object.
- Java
public class Data
{
private List<String> list = new ArrayList<>();
private Processor processor;
public Data(Processor processor)
{
this.processor = processor;
}
public void add(String entry)
{
this.list.add(entry);
this.processor.wake();
}
public String get(int index)
{
return this.list.get(index);
}
public String contains(String entry)
{
return this.list.contains(entry);
}
public int size()
{
return this.list.size();
}
}
public class Processor
{
private Data data = new Data(this);
private boolean isAsleep;
public void sleep()
{
this.isAsleep = true;
}
public void wake()
{
this.isAsleep = false;
}
public Data getData()
{
return this.data;
}
public void tick()
{
if(this.isAsleep) return;
if(this.data.contains("Test"))
{
sleep();
return;
}
int index = -1;
for(int i = 0; i < this.data.size() - 1; i++)
{
if(this.list.get(i).equals("Test"))
{
index = i;
break;
}
}
// Do something else
}
}
public static void main(String[] args)
{
Processor processor = new Processor();
while(true)
{
processor.tick();
// Do something else
}
}
There are even more applications for this model. For example consider an entity in a game with simulated physics. The object will cause collisions that have to be resolved even if the object just rests on the ground without any interactions. Collision resolution takes usually a long time. If the Wake/Sleep-Model is used it is possible to disable physics as long as no interactions like bumps or shots take place.
Schreibe einen Kommentar