Tag Archives: gateway

Use case: FIX messages processing. Part 2: writing and optimizing a FIX gateway

by Mikhail Vorontsov

Now, having a fast parsing method from the first part of this article, let’s try to implement a FIX gateway. Its purpose is to filter out some messages based on a some criteria. We wouldn’t discuss filtering in this article – it is very straightforward and very task-dependent. Instead we will see what we can do in order to optimize the gateway processing loop. For the beginning, let’s suppose that it is “parse-filter-compose message” loop. We have a parser, you have written a filter, now we need a compose method, which takes a list of parsed fields and returns a message string.

The following method uses a StringBuilder with initial size of 1024 bytes (it makes sense to use either average or maximal message length for StringBuilder initialization) to compose a message. It is rather straightforward, but contains a problem with double values: if values are big enough, they will be formatted in scientific “e”-notation, which means that we will not get an original message. Though, depending on the gateway clients, it may not be a problem – general purpose double parsers support scientific notation. You can read more about double -> String -> double conversion in BigDecimal vs double article.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//compose a message from a list of parsed fields
private static String compose( final List<Field> fields )
{
    boolean first = true;
    final StringBuilder sb = new StringBuilder( 1024 );
    for ( final Field fld : fields )
    {
        if ( first )
            first = false;
        else
            sb.append( FIELD_SEPARATOR_CHAR );
        sb.append( fld.id ).append( VALUE_SEPARATOR_CHAR );
        if ( DATE_FIELDS.get( fld.id ) )
            sb.append( DATE_FORMAT.get().format( fld.value ) );
        else if ( INT_FIELDS.get( fld.id ) )
            sb.append( Integer.toString( ( Integer ) fld.value ) );
        else if ( DOUBLE_FIELDS.get( fld.id ) )
            sb.append( Double.toString( ( Double ) fld.value ) );
        else
            sb.append( fld.value );
    }
    return sb.toString();
}
//compose a message from a list of parsed fields
private static String compose( final List<Field> fields )
{
    boolean first = true;
    final StringBuilder sb = new StringBuilder( 1024 );
    for ( final Field fld : fields )
    {
        if ( first )
            first = false;
        else
            sb.append( FIELD_SEPARATOR_CHAR );
        sb.append( fld.id ).append( VALUE_SEPARATOR_CHAR );
        if ( DATE_FIELDS.get( fld.id ) )
            sb.append( DATE_FORMAT.get().format( fld.value ) );
        else if ( INT_FIELDS.get( fld.id ) )
            sb.append( Integer.toString( ( Integer ) fld.value ) );
        else if ( DOUBLE_FIELDS.get( fld.id ) )
            sb.append( Double.toString( ( Double ) fld.value ) );
        else
            sb.append( fld.value );
    }
    return sb.toString();
}

Continue reading