All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.mostlyoriginal.api.event.dispatcher.ClassBasedDispatcherBenchmark Maven / Gradle / Ivy

There is a newer version: 2.5.0
Show newest version
package net.mostlyoriginal.api.event.dispatcher;

import com.artemis.Manager;
import com.artemis.World;
import com.artemis.WorldConfiguration;
import com.artemis.annotations.Wire;
import net.mostlyoriginal.api.MyBenchmark;
import net.mostlyoriginal.api.event.common.*;
import org.openjdk.jmh.annotations.*;

import java.util.concurrent.TimeUnit;

/**
 * Benchmark the dispatching of events, dispatch including event listeners.
 *
 * Intended for class based dispatchers, like the PollingPooledDispatcher.
 *
 * @author DaanVanYperen
 */
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS)
public abstract class ClassBasedDispatcherBenchmark extends MyBenchmark {

	public static final int DISPATCH_BATCH_SIZE = 1000;
	protected EventSystem em;
	private ActiveEventHandlers activeEventHandlers;

	/**
	 * Events with deep hierarchies apply to more event listeners,
	 * and generally have more overhead.
	 */
	public static class MassiveListenerEvent implements Event {}
	public static class EventNest0 implements Event {}
	public static class EventNest0v2 implements Event {}
	public static class EventNest1 extends EventNest0 {}
	public static class EventNest2 extends EventNest1 {}
	public static class EventNest3 extends EventNest2 {}
	public static class EventNest4 extends EventNest3 {}
	public static class EventNest5 extends EventNest4 {}
	public static class EventNest6 extends EventNest5 {}
	public static class EventNest7 extends EventNest6 {}
	public static class EventNest8 extends EventNest7 {}

	public static class IgnoredEvent01 implements Event {}
	public static class IgnoredEvent02 implements Event {}
	public static class IgnoredEvent03 implements Event {}
	public static class IgnoredEvent04 implements Event {}
	public static class IgnoredEvent05 implements Event {}
	public static class IgnoredEvent06 implements Event {}
	public static class IgnoredEvent07 implements Event {}
	public static class IgnoredEvent08 implements Event {}
	public static class IgnoredEvent09 implements Event {}
	public static class IgnoredEvent10 implements Event {}
	public static class IgnoredEvent11 implements Event {}
	public static class IgnoredEvent12 implements Event {}
	public static class IgnoredEvent13 implements Event {}
	public static class IgnoredEvent14 implements Event {}
	public static class IgnoredEvent15 implements Event {}
	public static class IgnoredEvent16 implements Event {}
	public static class IgnoredEvent17 implements Event {}
	public static class IgnoredEvent18 implements Event {}
	public static class IgnoredEvent19 implements Event {}
	public static class IgnoredEvent20 implements Event {}
	public static class IgnoredEvent21 implements Event {}
	public static class IgnoredEvent22 implements Event {}
	public static class IgnoredEvent23 implements Event {}
	public static class IgnoredEvent24 implements Event {}
	public static class IgnoredEvent25 implements Event {}
	public static class IgnoredEvent26 implements Event {}
	public static class IgnoredEvent27 implements Event {}
	public static class IgnoredEvent28 implements Event {}
	public static class IgnoredEvent29 implements Event {}
	public static class IgnoredEvent30 implements Event {}
	public static class IgnoredEvent31 implements Event {}
	public static class IgnoredEvent32 implements Event {}
	public static class IgnoredEvent33 implements Event {}
	public static class IgnoredEvent34 implements Event {}
	public static class IgnoredEvent35 implements Event {}
	public static class IgnoredEvent36 implements Event {}
	public static class IgnoredEvent37 implements Event {}
	public static class IgnoredEvent38 implements Event {}
	public static class IgnoredEvent39 implements Event {}
	/**
	 * These will cause the EventNest0 handler to be called.
	 * Typical use case would be a superclass event handler
	 * that accepts a lot of different event subclasses.
 	 */
	public static class EventNest1NoImmediateHandler extends EventNest0 {}
	public static class EventNest2NoImmediateHandler extends EventNest1NoImmediateHandler {}

	/** Give the dispatcher some padding to deal with. Dispatchers that
	 * do not prep event lists will perform badly.
	 */
	@Wire
	public static class PaddingHandlers extends Manager {
		@Subscribe public void notUsedHandler01( IgnoredEvent01 event ) {}
		@Subscribe public void notUsedHandler02( IgnoredEvent02 event ) {}
		@Subscribe public void notUsedHandler03( IgnoredEvent03 event ) {}
		@Subscribe public void notUsedHandler04( IgnoredEvent04 event ) {}
		@Subscribe public void notUsedHandler05( IgnoredEvent05 event ) {}
		@Subscribe public void notUsedHandler06( IgnoredEvent06 event ) {}
		@Subscribe public void notUsedHandler07( IgnoredEvent07 event ) {}
		@Subscribe public void notUsedHandler08( IgnoredEvent08 event ) {}
		@Subscribe public void notUsedHandler09( IgnoredEvent09 event ) {}
		@Subscribe public void notUsedHandler10( IgnoredEvent10 event ) {}
		@Subscribe public void notUsedHandler11( IgnoredEvent11 event ) {}
		@Subscribe public void notUsedHandler12( IgnoredEvent12 event ) {}
		@Subscribe public void notUsedHandler13( IgnoredEvent13 event ) {}
		@Subscribe public void notUsedHandler14( IgnoredEvent14 event ) {}
		@Subscribe public void notUsedHandler15( IgnoredEvent15 event ) {}
		@Subscribe public void notUsedHandler16( IgnoredEvent16 event ) {}
		@Subscribe public void notUsedHandler17( IgnoredEvent17 event ) {}
		@Subscribe public void notUsedHandler18( IgnoredEvent18 event ) {}
		@Subscribe public void notUsedHandler19( IgnoredEvent19 event ) {}
		@Subscribe public void notUsedHandler20( IgnoredEvent20 event ) {}
		@Subscribe public void notUsedHandler21( IgnoredEvent21 event ) {}
		@Subscribe public void notUsedHandler22( IgnoredEvent22 event ) {}
		@Subscribe public void notUsedHandler23( IgnoredEvent23 event ) {}
		@Subscribe public void notUsedHandler24( IgnoredEvent24 event ) {}
		@Subscribe public void notUsedHandler25( IgnoredEvent25 event ) {}
		@Subscribe public void notUsedHandler26( IgnoredEvent26 event ) {}
		@Subscribe public void notUsedHandler27( IgnoredEvent27 event ) {}
		@Subscribe public void notUsedHandler28( IgnoredEvent28 event ) {}
		@Subscribe public void notUsedHandler29( IgnoredEvent29 event ) {}
		@Subscribe public void notUsedHandler30( IgnoredEvent30 event ) {}
		@Subscribe public void notUsedHandler31( IgnoredEvent31 event ) {}
		@Subscribe public void notUsedHandler32( IgnoredEvent32 event ) {}
		@Subscribe public void notUsedHandler33( IgnoredEvent33 event ) {}
		@Subscribe public void notUsedHandler34( IgnoredEvent34 event ) {}
		@Subscribe public void notUsedHandler35( IgnoredEvent35 event ) {}
		@Subscribe public void notUsedHandler36( IgnoredEvent36 event ) {}
		@Subscribe public void notUsedHandler37( IgnoredEvent37 event ) {}
		@Subscribe public void notUsedHandler38( IgnoredEvent38 event ) {}
		@Subscribe public void notUsedHandler39( IgnoredEvent39 event ) {}
	}

	@Wire
	public static class ActiveEventHandlers extends Manager {

		int count=0;

		@Subscribe
		/* This will handle EventNest0 and all higher events, so will be called the most! */
		public void handle0 ( EventNest0 event ) { count++; }

		@Subscribe
		public void handlev2 ( EventNest0v2 event ) { count++; }

		@Subscribe
		/* This will handle EventNest1 and all higher events, so will be called less. */
		public void handle1 ( EventNest1 event ) { count++; }
		@Subscribe
		/* .. */
		public void handle2 ( EventNest2 event ) { count++; }
		@Subscribe

		public void handle3 ( EventNest3 event ) { count++; }
		@Subscribe
		public void handle4 ( EventNest4 event ) { count++; }
		@Subscribe
		public void handle5 ( EventNest5 event ) { count++; }
		@Subscribe
		public void handle6 ( EventNest6 event ) { count++; }
		@Subscribe
		public void handle7 ( EventNest7 event ) { count++; }
		@Subscribe
		public void handle8 ( EventNest8 event ) { count++; }


		@Subscribe public void h01( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h02( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h03( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h04( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h05( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h07( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h08( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h09( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h10( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h11( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h12( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h13( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h14( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h15( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h17( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h18( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h19( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h20( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h21( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h22( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h23( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h24( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h25( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h27( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h28( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h29( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h30( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h31( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h32( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h33( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h34( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h35( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h37( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h38( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h39( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h40( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h41( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h42( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h43( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h44( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h45( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h47( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h48( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h49( MassiveListenerEvent event ) { count++; }
		@Subscribe public void h50( MassiveListenerEvent event ) { count++; }
	}


	@Setup
	public void setup()
	{
		final WorldConfiguration config = new WorldConfiguration();

		em = new EventSystem(instanceDispatcher(), new SubscribeAnnotationFinder());
		config.setSystem(em);
		activeEventHandlers = new ActiveEventHandlers();
		config.setSystem(activeEventHandlers);
		config.setSystem(new PaddingHandlers());

		World w = new World(config);
	}

	protected abstract EventDispatchStrategy  instanceDispatcher();

	@Benchmark
	@OperationsPerInvocation(DISPATCH_BATCH_SIZE)
	public void eventWithNoHierarchyAndOneHandler()
	{
		// eventNest0 events apply only to handle0 listener.
		for (int i = 0; i < DISPATCH_BATCH_SIZE; i++) {
			em.dispatch(EventNest0.class);
		}
		em.process();
	}

	protected void dispatch(Event event) {
		em.dispatch(event);
	}

	@Benchmark
	@OperationsPerInvocation(DISPATCH_BATCH_SIZE)
	public void eventWithHierarchyAndOneHandler()
	{
		//
		for (int i = 0; i < DISPATCH_BATCH_SIZE; i++) {
			em.dispatch(EventNest2NoImmediateHandler.class);
		}
		em.process();
	}

	@Benchmark
	@OperationsPerInvocation(DISPATCH_BATCH_SIZE)
	public void eventWithManySubclassListeners()
	{
		// eventNest0 events applies to handle0-8 listeners.
		// Also has a deep hierarchy.
		for (int i = 0; i < DISPATCH_BATCH_SIZE; i++){
			em.dispatch(EventNest8.class);
		}
		em.process();
	}


	@Benchmark
	@OperationsPerInvocation(DISPATCH_BATCH_SIZE*2)
	public void eventWithMixedCalls()
	{
		// mix up calls, just to see how it works.
		for (int i = 0; i < DISPATCH_BATCH_SIZE; i++) {
			em.dispatch(EventNest0.class);
			em.dispatch(EventNest0v2.class);
		}
		em.process();
	}

	@Benchmark
	@OperationsPerInvocation(DISPATCH_BATCH_SIZE)
	public void eventWithFiftyListeners()
	{
		// has many listeners.
		for (int i = 0; i < DISPATCH_BATCH_SIZE; i++) {
			em.dispatch(MassiveListenerEvent.class);
		}
		em.process();
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy