Environment

Sender Host:

Receiver Host:

Test scenario

The test scenario is the following:

During the test Round-trip time (RTT) latency is measured. The first measurement, t1, is made before the message is sent by the Initiator, the second, t2, is made after the received message is parsed by the Initiator.

RTT=t2-t1.

Test configurations

Properties
BalancedOptimized
Nagle's algorithm1

Message validation parametersvalidateCheckSum

validateGarbledMessage
Storage type
PersistentIn memory
Queue type
PersistentIn memory

Nagle's algorithm1 - the algorithm aimed at reducing the number of packets that need to be sent over the network. Nagle's algorithm works by combining a number of small outgoing messages and sending them all at once.

The following description will help to choose the most relevant FIX Antenna Java configuration:

Results

FIX Antenna Java configurations comparison

ConfigurationBalancedOptimized
Latency values (microseconds)
Min
39,927,2
Max
1442,31200,7
Average45,831,1
Latency distribution (percentiles)
50%4329,5
95%62,639,3
99%74,857,6

FIX Antenna Java 2.15.27 vs QuickFIX Java 1.6.3

The benchmark code was ported to QuickFIXJ:

public final class RoundTripTester extends ApplicationAdapter {
    ..
    private void sendMessage() throws IOException {
        workMessage.getHeader().setInt(MsgSeqNum.FIELD, workMessageSequence++);
        start = System.nanoTime();
        session.send(workMessage);
    }
 
     
    @Override
    public void fromApp(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
            long end = System.nanoTime();
            String type = message.getHeader().getString(MsgType.FIELD);
            if (workMessageType.equals(type)) {
                final long currentLatency = end - start;
                latencies[counter++] = currentLatency;
                if (limitEnabled) {
                    long nextSendTime = testStart + (counter * sendIntervalMsec);
                    while (true) {
                        long currentTime = System.currentTimeMillis();
                        long toSleep = nextSendTime - currentTime;
                        if (toSleep <= 0) {
                            break;
                        }
                    }
                }
 
                if (counter == NO_OF_MESSAGES) {
                    //print results
                } else {
                    sendMessage();
                }
            } else if (warmUpMessageType.equals(type)) {
                warmUpCounter++;
                if(warmUpCounter == WARM_UP_CYCLE_COUNT){
                    log.info("Warm up cycle has been done");
                    testStart = System.currentTimeMillis();
                    sendMessage();
                }
            }
    }
    ...
  public final class RoundTripServer extends ApplicationAdapter {
    ....
    @Override
    public void fromApp(Message message, SessionID sessionId) {
         try {
            String type = message.getHeader().getString(MsgType.FIELD);
            if("D".equals(type)) {
                executionReport.setString(ClientID.FIELD, message.getString(ClientID.FIELD));
                executionReport.setString(Price.FIELD, message.getString(Price.FIELD));
                executionReport.setString(OrderQty.FIELD, message.getString(OrderQty.FIELD));
                executionReport.setString(TransactTime.FIELD, message.getString(TransactTime.FIELD));
                executionReport.setInt(ExecID.FIELD, ++execID);
                executionReport.setInt(OrderID.FIELD, ++orderID);
                Session.sendToTarget(executionReport, sessionId);
            } else {
                Session.sendToTarget(message, sessionId);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
...


Results can be compared in the following table:

Configuration

FIXAntenna Java
balanced
FIXAntenna Java optimizedQuickFIXJ defaultQuickFIXJ optimized
Latency values (microseconds)

Min

39,927,285,770,0
Max1442,31200,73891,843565,9
Average45,831,1258,0258,0
Latency distribution (Percentiles)
50%43,029,5113,5114,3
95%62,639,3182,1165,0
99%74,857,62107,01336,4