Minborg

Minborg
Minborg

Thursday, December 15, 2016

Day 15, Java Holiday Calendar 2016, Don't Optimize Now!

15. Don't Optimize Now!





Today's tips is about how the JVM can optimize our code. Back in the good ol' Java 1.0 days, I remember running programs that replaced the names of variables, classes and methods so they would become shorter, presumably resulting in faster execution. When things blew up in our faces, we were clueless what really happened because the NPE that method c threw in class D that inherited from class A just didn't provide adequate information as to what really went wrong. It was better before.... not...

These days, the present JVM is just incredible improved over its first incarnations. The JVM will collect statistics on how methods are used and then use that piece of information when it eventually will compile the method with its Just-In-Time (JIT) compiler. This often takes place when a method has been called for about 10 000 times. This is one reason why we should "warm up" our code properly before we run benchmarks.

The JVM is also using a scheme called Code Flattening which means that it is able to "roll up" method calls and consider the code as a larger flow of operations. This way, it is able to determine the possible paths the program can take and consider these paths individually and optimize them. For example, identical range checking that takes place in several methods that call each other can be eliminated. Another example is that dead paths (e.g. where an "if"-branch is using a constant expression) can be eliminated all together.

Another means of optimization is Escape Analysis that is used to determine if an object is visible outside a certain scope. If not, the object can be allocated on the stack rather then on the heap making the program run much faster. Consider the following code snippet:

    @Override 
    public String toString() {
      final StringBuilder sb = new StringBuilder()
        .append("(")
        .append(x)
        .append(", ")
        .append(y)
        .append(")");
      return sb.toString();
  }

Once this code is compiled and when the method has been called a predetermined number of times, the JVM will allocate the StringBuilder on the stack rather than on the heap. Once the method returns, the StringBuilder is cleaned up automatically when the stack is popped upon its return. Because the object cannot be observed from outside, it is also possible to use a simplified representation of the StringBuilder on the stack. So, effectively, the StringBuilder never exists and thus putting in a lot of work to eliminate it is waisted work and will only result in code that looks bad.

One cool thing is that the JVM can combine its optimization schemes. For example, with code flattening, much larger scopes can be used for escape analysis and objects that actually do escape a method might be re-catch on a higher "rolled up" level. Such objects may be subject to stack allocation too. Amazing stuff! 

There are two golden rules when it comes to optimization:

1) Don't optimize
2) Don't optimize now...

That said, when we want to write performance critical applications, it is important to have a basic understanding of the JVM to really know what is going on under the hood. Sometimes it really pays of to rewrite and optimize code.

Speedment, an open-source stream ORM tool and runtime, relies on a number of JVM features to be able to provide efficient execution of its own and application Java code. In particular, the stream implementations benefit substantially from code flattening and escape analysis.

Know your JVM an put your effort where it matters and not in places the JVM will optimize anyhow.

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.



Wednesday, December 14, 2016

Day 14, Java Holiday Calendar 2016, Submitting a Task


14. Submitting a Task



Today's tips is about submitting tasks. Historically, we java developers commonly used a new Thread directly when we wanted something to be done in parallel with the current thread. These days, there are a number of other better and more convenient ways of getting the job done.

For the sake of simplicity, we assume that we have a task we want to run that does not return something. This can be modeled using the Runnable interface and we can use lambdas to express our tasks.

Here are a number of alternate ways to execute a task:

public class Main {

    public static void main(String[] args) {
        // Runs in the main thread 
        helloWorld();

        // Runs in a new thread
        new Thread(Main::helloWorld).start();

        // Runs in the default fork join pool
        ForkJoinPool.commonPool().submit(Main::helloWorld);

        // Runs in the default fork join pool via a CompletableFuture
        CompletableFuture.runAsync(Main::helloWorld);

        // Runs in a custom fork join pool (with three workers)
        new ForkJoinPool(3).submit(Main::helloWorld)

        // Queues up task in a single thread executor
        Executors.newSingleThreadExecutor().execute(Main::helloWorld);

        // Caches tasks so that short lived re-occurring tasks can execute faster
        Executors.newCachedThreadPool().execute(Main::helloWorld);

        // Runs in a separate thread pool with the given delay
        Executors.newScheduledThreadPool(2).schedule(Main::helloWorld, 10, TimeUnit.MILLISECONDS);
    }

    public static void helloWorld() {
        System.out.println("Hello World greeting from " + Thread.currentThread().getName());
    }

}

This will produce the following print out:

Hello World greeting from main
Hello World greeting from Thread-0
Hello World greeting from ForkJoinPool.commonPool-worker-1
Hello World greeting from ForkJoinPool.commonPool-worker-1
Hello World greeting from ForkJoinPool-1-worker-1
Hello World greeting from pool-1-thread-1
Hello World greeting from pool-2-thread-1
Hello World greeting from pool-3-thread-1

Remember that in a real case scenario, we need to shut down the custom thread pools we are creating or else our program will not terminate properly (because there are still live threads alive). Closing a thread pool can be made like this:

try {
     forkJoinPool.shutdown();
     forkJoinPool.awaitTermination(1, TimeUnit.HOURS);
 } catch (InterruptedException ie) {
     ie.printStackTrace();
 } 

Read more on thread executing principles on DZone here.

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season. I am contributing to open-source Speedment, a stream based ORM tool and runtime. Please check it out on GitHub.

Tuesday, December 13, 2016

Day 13, Java Holiday Calendar 2016, Try Higher Order of Functionality

13. Higher Order of Functionality



Today's tips is to explore the world of Higher Order Functionality and how to work with functions that operates on functions.

In the good old pre-Java 8 days, algorithms mostly operated on data structures. But with the introduction of  functions in Java 8, our programs may now also reason about behavior. Programming a program that operates on other programs opens up a whole new level of abstractions which allows for elegant declarative programs that express what to be done rather than how, leaving the details about the execution to a framework that performs the operation from "what" to "how" as a higher order operation.

We could, for example, write a QuickSort algorithm that may sort anything (that extends Object) stored anyhow by just providing functional parameters in the form of a getter,  a comparer, a swapper and the number of elements to sort. This enables the QuickSort algorithm to sort lists, arrays or even serialized off heap objects using the same basic algorithm. The QuickSort algorithm just applies the provided functions agnostically. Thus, we only need to write QuickSort once and then we can re-use it by just providing the appropriate functions.

Speedment is an Open Source ORM with an API founded on Java 8 streams. With Speedment you can apply functions that takes functions as a parameter. For example you can:

users.stream()
  .filter(User.BORN.between(1985, 1995)) // Filters out Users born 1985 up to and including 1994
  .map(User.CATEGORY.setTo(3))           // Applies a function that sets their category to 3
  .forEach(users.updater());             // Applies the updater function to the selected users

The code snippet above will;

a) extract users from an underlying database where the users are born between 1985 and 1995 (and only those users)
b) for each such user, it will apply a mapping from a user to an updated user where the category has been set to 3 (but all other fields remain the same)
c) for each updated user, a database updater method will be applied that will result in the updated user being persisted in the database.

So, the snippet above is a sequence of methods that are provided other methods as per the paradigm of Higher Order of Functionality. If we later elect to store our data not in a database but in a file, in memory or even in an Excel diagram, then we only need to provide another set of functions. The stream logic will remain exactly the same.


Read more on Higher Order of Functionality here.

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Monday, December 12, 2016

Day 12, Java Holiday Calendar 2016, Avoid Overloading with Lambdas

12. Avoid Overloading with Lambdas




Today's tips is to think twice about the names you assign to you methods that can receives lambdas and avoid letting them share the same name.

If there are two or more methods with the same name that take functional interfaces as parameters, then this would likely create a lambda ambiguity on the client side. For example, if there are two Point methods add(Function<Point, String> renderer) and add(Predicate<Point> logCondition) and we try to call point.add(p -> p + “ lambda”) from the client code, the compiler is unable to determine which method to use and will produce an error. Instead, consider naming methods according to their specific use.

I have contributed a lot to the open-source stream based ORM project Speedment and there we have used this naming convention, allowing lambdas to be used in a good way throughout the API.

Do This:

public interface Point {
    addRenderer(Function<Point, String> renderer);
    addLogCondition(Predicate<Point> logCondition);
}


Don't do This:

public interface Point {
    add(Function<Point, String> renderer);
    add(Predicate<Point> logCondition);
}


Read more on Java 8 API design principles on DZone here.

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Sunday, December 11, 2016

Day 11, Java Holiday Calendar 2016, Try JavaFX

11. Building Reactive Systems with JavaFX




Today's tips is to take the leap from Swing to JavaFX, the latter being much more modern and feature full than the former. 

The open-source Speedment UI tool is built using JavaFX, allowing the tool to be more reactive, in the sense that if we change something in a text box, for example, that property can affect other components directly and dynamically. E.g. if we change the name of a schema, then a tree component showing the entire database structure is updated in real time and perhaps also a connection URL that depends on the schema name. Here is the complete UI tool code written using JavaFX.

Properties and Observability

Property objects are important when designing JavaFX applications. Almost everything in the FX library can be observed such as the text content of a field, the position of a slider or the status of a checkbox. Properties can be Writable and Readable. A writable value can be updated using its setter or by user interaction with the component whereas a readable can react (via notifications) to external events.

Here is how it looks like:

// Both readable and writable
StringProperty name = new SimpleStringProperty("Schema Name"); 

// Only readable
ObservableBooleanValue nameIsEmpty = name.isEmpty();

So, the variable nameIsEmpty can return true if the name is currently empty or false if name is non-empty.

Bindings

Now that we have writable and readable values, we can define custom rules how they all relate to each other (e.g. we can "wire up" our model). Bindings are either unidirectional or bidirectional. Unsurprisingly, bidirectional bindings requires that both properties are writable.

Here is an example of binding:

TextField firstField  = new TextField("first");
TextField secondField = new TextField("second");
firstField.prefWidthProperty().bind(secondField.widthProperty());

This will hint JavaFX that we want our firstTextField to have the same width that the secondField. This relation will be maintained over time so if we change the secondField's width, then the firstField's hinted width is updated automatically.

Tips

JavaFX can be combined with other reactive libraries such as ReactFX and RxJavaFX to create even more powerful applications.

Read more on JavaFX on DZone here and here (Refcardz).

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Saturday, December 10, 2016

Day 10, Java Holiday Calendar 2016, MapStream

Day 10, Java Holiday Calendar 2016, MapStream



Today's tips is about the open-source class MapStream that allows us to stream not only over elements but over pair of key, value elements and make changes either to the keys, values or both.

You can find the source code for MapStream here together with some examples of how to use it. It is free so go ahead and use or copy it in your application! MapStream is a part of open-source Speedment, a stream ORM tool and runtime.

With MapStream you can do this:

Map<String, Integer> numberOfCats = new HashMap<>();

numberOfCats.put("Anne", 3);
numberOfCats.put("Berty", 1);
numberOfCats.put("Cecilia", 1);
numberOfCats.put("Denny", 0);
numberOfCats.put("Erica", 0);
numberOfCats.put("Fiona", 2);

System.out.println(
  MapStream.of(numberOfCats)
      .filterValue(v -> v > 0)
      .sortedByValue(Integer::compareTo)
      .mapKey(k -> k + " has ")
      .mapValue(v -> v + (v == 1 ? " cat." : " cats."))
      .map((k, v) -> k + v)
      .collect(Collectors.joining("\n"))
);

This would produce the following:

Cecilia has 1 cat.
Berty has 1 cat.
Fiona has 2 cats.
Anne has 3 cats.

Learn more on MapStream here.

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.




Friday, December 9, 2016

Day 9, Java Holiday Calendar 2016, Event Sourcing

9. Event Sourcing



Today's tips is about Event Sourcing which is a relatively new way of designing database applications. Instead of seeing the database as a representation of the most current state, we would see it as a system of record for all transactions that ever took place in our applications. 

So, instead of saying "find person 3 and replace that persons salary with whatever it is right now plus $100" we would say "person 3's salary increased by $100". Note the subtile but important distinction. 

If we use the first scheme, then we would know the current salary but not what it was before, by how much it increased and when it increased. The latter scheme however, allows us to replay all transactions so that we can re-produce all states the application ever had. Great when we are hunting bugs. 

Another important property of event sourcing is that we do not need the (expensive) absolute consistency of the underlying database. Instead, we only need to make sure that the order of the events remain consistent over time.

How do we keep track of the most recent value in an event sourcing system when it is changing all the time? Well, we could implement something called a Materialized View that holds the most current state. So, if we have an event table called employee_events then we could have a Java class EmployeeView that continuously will replay the events in the employees_event table and distiller the fold of all events so that we would actually know what salary person 3 has at the moment.

When the number of events increases, it would be more and more expensive to fast forward all the events, for example when the application restarts. To combat this drawback, the EmployeeView could create periodic snapshots from which it can be restarted. 

Event Sourcing is particularly interesting for applications with a micro service architecture.

Read more about Event Sourcing on Emil Forslund's blog here and on Event Sourcing and Micro Services on eventuate.io here.

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.