DigitalJoel

2015/10/06

Iterative Code vs. Reactive Code

Filed under: development, java, rxJava — Tags: , — digitaljoel @ 4:45 pm

At work we have an internal app that downloads a large JSON file and uses angular to create tables and allows for filtering and whatnot.  The user interface is SUPER slow.  Basically unusable, and it didn’t give me the data in the format I needed.  So, I decided to take the giant JSON dump and parse it with a little java program and output the information I need.  The JSON data looks like this:

apps – an ordered list of strings.

gavs – an ordered list of strings.

hosts – an ordered list of strings.

uses – a list of 3-item integer arrays where the first item in the array is the index into the app collection, the second is the index into the gavs collection, and the third is an index into the hosts collection.  Something like [45, 67, 189] would mean that it references the app at the 45th index, the gav at the 67th, and the host at the 189th.

I needed to get a list of all apps that are associated with certain gavs.  So my first pass was an iterative solution. It looked something like this:

public static void main( String... args ) {
    for ( blah : blah ) // stuff that gets the gavIndex I'm interested in...
        for ( List<Integer> use : uses ) {
            // if the index in the gav collection matches the gav that I'm testing now
            if ( gavIndex == use.get(1)) {
                // get the app string from the apps collection so I can show a user friendly
                // app name instead of just an index.
                String app = apps.get(use.get(0));
                // references is a multimap that is storing my apps per gav.
                if ( references.get(app) == null || !references.get(app).contains(module)) {
                    // so put the reference in the multimap if it's not already there.
                    references.put(app, module );
                }
            }
        }
    }
    // code to output my references.
}

Now the reactive code:

public static void main( String... args ) {
    PublishSubject<List<Integer>> subject = PublishSubject.create();
    for ( blah : blah ) // stuff that gets the gavIndex I'm interested in...
        subject
            .filter(use -> shouldInsert( apps, use, gavIndex, module, references))
            .subscribe(use -> references.put(apps.get(use.get(0)), module));
    }
    Observable.from(uses).subscribe(subject);
    // code to output my references.
}
// basically the condition that was inline in the iterative solution.
private static boolean shouldInsert( List<String> apps, List<Integer> use, int gavIndex, String module, Multimap<String, String> references ) {
    Collection<String> currentUses = references.get(apps.get(use.get(0)));
    boolean result = (gavIndex == use.get(1)) && (currentUses == null || !currentUses.contains( module ));
    return result;
}

I get the same result from both processes. The reactive I find interesting because I just set everything up, then when the subject subscribes to the observable it all just goes. I also think the succinctness of the reactive code is actually easier to read.

Are there fewer lines? Not really, and that shouldInsert method sure takes a lot of parameters. Currently it’s not thread safe, but I could get there easily, and then I would expect the reactive version to be faster than the iterative. Finally, the question is, what does rx buy me over java 8 streams in this case? Not really anything, but I don’t have a ton of experience with java 8 streams yet, and sadly I don’t have time to mess with it currently. Anyway, it was interesting to me, and thought it might be interesting to others.

Create a free website or blog at WordPress.com.