martes, 18 de agosto de 2015

Multi-threading in a common loop

Usually, we are doing a lot of loops as a programmer, it is a basic control method of the workflow. But, sometimes loops have bad performance because they do some heavy things.

public List<Output> getOutputFromKeys(final Collection<String> keys) {
    final List<Output> outputs = Lists.newArrayList();
    for (String key : keys) {
        outputs.add(getOutput(key));
    }
    return outputs;
}
 
This for-loop could be heavy depends on how long "getOutput" method takes. If the method takes lots of time, we will need improve the performance of that.
To improve the performance, we can take in advance the ExecutorService class of the Java.

public List<Output> getOutputFromKeys(final Collection<String> keys) {
    final int threads = Runtime.getRuntime().availableProcessors();
    final ExecutorService service = Executors.newFixedThreadPool(threads);





 

    class LoadOutput implements Callable<Output> {
        private String key; 
        public LoadOutput(final String key) {
            this.key = key;
        }

        @Override
        public Output call() throws Exception {
            final Output out = getOutput(key);
            if (out == null) {
                logger.warn(String.format("Output with key %s is null", key));
            }
            return out;
        }
    }

    final List<Future<Output>> futures = Lists.newArrayList();
    for (final String key : keys) {
        final LoadOutput callable = new LoadOutput(key);
        futures.add(service.submit(callable));
    }

    service.shutdown();

    return Lists.newArrayList(Collections2.transform(futures, new Function<Future<Output>, Output>() {
            @Nullable 
            @Override 
            public Output apply(Future input) {
                Output out = null;
                try {
                    out = input.get();
                } catch (Exception e) {
                    logger.error("There was an error with multithreading.", e);
                }
                return out;
            }
    }));
}

The improvement use multi-threading to improve the for-loop and use callback methods. That can help us to improve our performance.