Hi,
I'm not sure if I'm doing a valid like for like comparison. But I have an Events that basically contain two doubles.
I have events for Add, Sub, Mult and Div - each does an addition, subtraction etc... of the two doubles and writes
the result into an instance of a inner 'State' class.
The code below show the Java and C# versions that are meant to be identical, but on the same machine,
repeated test show that the Java version is about 50% faster, I think it may be do the ExecuteService parameter.
Any ideas on what I may be doing wrong with C# version - see below?
Regards
Mike Lewis
Java:
-------
ExecutorService service = Executors.newFixedThreadPool(7);
Disruptor<CalculationEvent> disruptor = new Disruptor<>(CalculationEvent.EVENT_FACTORY,65536,service);
final EventHandler<CalculationEvent> adder = new EventHandler<CalculationEvent>() {
@Override
public void onEvent(CalculationEvent calculationEvent, long sequenceId, boolean endOfBatch) throws Exception {
calculationEvent.doCalc(CalculationEvent.Type.add);
}
};
final EventHandler<CalculationEvent> subtractor = new EventHandler<CalculationEvent>() {
@Override
public void onEvent(CalculationEvent calculationEvent, long sequenceId, boolean endOfBatch) throws Exception {
calculationEvent.doCalc(CalculationEvent.Type.sub);
}
};
final EventHandler<CalculationEvent> multiplier = new EventHandler<CalculationEvent>() {
@Override
public void onEvent(CalculationEvent calculationEvent, long l, boolean b) throws Exception {
calculationEvent.doCalc(CalculationEvent.Type.mult);
}
};
final EventHandler<CalculationEvent> divider = new EventHandler<CalculationEvent>() {
@Override
public void onEvent(CalculationEvent calculationEvent, long l, boolean b) throws Exception {
calculationEvent.doCalc(CalculationEvent.Type.div);
}
};
final EventHandler<CalculationEvent> publishResult1 = new EventHandler<CalculationEvent>() {
@Override
public void onEvent(CalculationEvent calculationEvent, long l, boolean b) throws Exception {
/*
no-op
*/
}
};
/*
* This says do add, sub, mult, div in parallel and then do finish.
*/
disruptor.handleEventsWith(adder,subtractor,multiplier,divider).then(publishResult1);
RingBuffer<CalculationEvent> ringBuffer = disruptor.start();
CalculationEventTranslator translator = new CalculationEventTranslator();
long s = (System.currentTimeMillis());
//Random r = new Random();
for (int i=0; i<1500000; ++i) {
double first = 0.5; //r.nextDouble();
double second = 0.5; // r.nextDouble();
ringBuffer.publishEvent(translator,first,second);
}
System.out.println("time spent "+ (System.currentTimeMillis() - s) + " ms");
disruptor.shutdown();
service.shutdown();
}
C#
--
var stopWatch = new Stopwatch();
var distruptor = new Disruptor.Dsl.Disruptor<CalculationEvent>(() => new CalculationEvent(), 65536,
TaskScheduler.Default);
var adder = new Adder();
var subtractor = new Subtractor();
var multiplier = new Multiplier();
var divider = new Divider();
var publisher = new Publisher();
distruptor.HandleEventsWith(new IEventHandler<CalculationEvent>[]
{
adder, subtractor, multiplier, divider
}).Then( publisher);
var buffer = distruptor.Start();
stopWatch.Start();
//var r = new Random();
for (var i = 0; i < 1500000; ++i)
{
double first = 0.5; //r.NextDouble();
double second = 0.5; // r.NextDouble();
var sequence = buffer.Next();
var entry = buffer[sequence];
entry.SetCalculationDetails(first,second);
buffer.Publish(sequence);
}
stopWatch.Stop();
Console.WriteLine("Time spent {0} ms",stopWatch.ElapsedMilliseconds);
distruptor.Shutdown();
Handlers:
public class Adder : IEventHandler<CalculationEvent>
{
public void OnNext(CalculationEvent data, long sequence, bool endOfBatch)
{
data.DoCalc(CalculationEvent.OpCode.Add);
}
}
public class Subtractor : IEventHandler<CalculationEvent>
{
public void OnNext(CalculationEvent data, long sequence, bool endOfBatch)
{
data.DoCalc(CalculationEvent.OpCode.Sub);
}
}
public class Multiplier : IEventHandler<CalculationEvent>
{
public void OnNext(CalculationEvent data, long sequence, bool endOfBatch)
{
data.DoCalc(CalculationEvent.OpCode.Mult);
}
}
public class Divider : IEventHandler<CalculationEvent>
{
public void OnNext(CalculationEvent data, long sequence, bool endOfBatch)
{
data.DoCalc(CalculationEvent.OpCode.Div);
}
}
public class Publisher : IEventHandler<CalculationEvent>
{
public void OnNext(CalculationEvent data, long sequence, bool endOfBatch)
{
}
}
Event Class:
using System;
public class CalculationEvent
{
public enum OpCode
{
Add, Sub, Div, Mult
};
public class State
{
public double Add { get; set; }
public double Sub { get; set; }
public double Mult { get; set; }
public double Div { get; set; }
}
private double _first;
private double _second;
public State CalcState;
public CalculationEvent()
{
CalcState = new State();
}
public void SetCalculationDetails(double first, double second)
{
_first = first;
_second = second;
}
public void DoCalc(OpCode code)
{
try
{
switch (code)
{
case OpCode.Add:
{
CalcState.Add = _first + _second;
}
break;
case OpCode.Div:
{
CalcState.Div = _first/_second;
}
break;
case OpCode.Mult:
{
CalcState.Mult = _first*_second;
}
break;
default:
{
CalcState.Sub = _first - _second;
}
break;
}
}
catch (Exception e)
{
}
}
}