Is Nashorn (JVM) faster than Node (V8)?

The answer to the question “Is Nashorn (JVM) faster than Node (V8)?” is in most people’s minds: a foregone conclusion, looking something like this expression.

no-way-9yykt8

It certainly was in my mind, until I actually ran a very simple benchmark that computes the Fibonacci sequence a few times (recursively). It’s a common enough benchmark, one frequently used to test method dispatching, recursion and maths in various languages / virtual machines. For disclosure, the code is listed below:

function fib(n) {
  if (n < 2)
    return 1;
  return fib(n - 2) + fib(n - 1);
}

try {
  print = console.log;
} catch(e) {
}

for(var n = 30; n <= 50; n++) {
  var startTime = Date.now();
  var returned = fib(n);
  var endTime = Date.now();
  print(n + " = " + returned + " in " + (endTime - startTime));
}

The results are, lets just say: “shocking”. The table below is both runs along side each other, the last numbers are the important ones: how many milliseconds each run took.

jason@Bender ~ $ node fib.js 
30 = 1346269 in 12
31 = 2178309 in 17
32 = 3524578 in 27
33 = 5702887 in 44
34 = 9227465 in 69
35 = 14930352 in 113
36 = 24157817 in 181
37 = 39088169 in 294
38 = 63245986 in 474
39 = 102334155 in 766
40 = 165580141 in 1229
41 = 267914296 in 2009
42 = 433494437 in 3241
43 = 701408733 in 5302
44 = 1134903170 in 8671
45 = 1836311903 in 13626
46 = 2971215073 in 22066
47 = 4807526976 in 45589
48 = 7778742049 in 74346
49 = 12586269025 in 120254
50 = 20365011074 in 199417
jason@Bender ~ $ jjs -ot fib.js 
30 = 1346269 in 70
31 = 2178309 in 16
32 = 3524578 in 19
33 = 5702887 in 30
34 = 9227465 in 48
35 = 14930352 in 76
36 = 24157817 in 123
37 = 39088169 in 197
38 = 63245986 in 318
39 = 102334155 in 517
40 = 165580141 in 835
41 = 267914296 in 1351
42 = 433494437 in 2185
43 = 701408733 in 3549
44 = 1134903170 in 5718
45 = 1836311903 in 9306
46 = 2971215073 in 15031
47 = 4807526976 in 34294
48 = 7778742049 in 38446
49 = 12586269025 in 61751
50 = 20365011074 in 100343

So what on earth is going on here? How can it be that the last result is 99 seconds faster on the Java VM than on V8, one of the fastest JavaScript engines on the planet?

The answer is actually hidden at the top of the tables: the -ot option being passed to JJS (Java JavaScript) is the key to this magic sauce. OT stands for Optimistic Typing, which aggressively assumes that variables are all compatible with the Java int type, and then falls back to more permissive types (like Object) when runtime errors happen. Because the code above only ever produces int values, this is a very good assumption to make and allows the Java VM to get on and optimise the code like crazy, where V8 continues to chug along with JavaScript’s Number type (actually it is more intelligent than that, but it’s just not showing in this little benchmark).

The point of this post is: don’t believe everything you read in benchmarks. They are very dependant on the code being run, and micro-benchmarks are especially dangerous things. The work that has been done on Optimistic Typing in Nashorn is amazing, and makes it a very attractive JavaScript environment. But you shouldn’t believe that just because these benchmarks show such a wide gap in performance that your Express application would run faster in Nashorn than under V8… In fact you’d be lucky to get it to run at all.

Feel free to replicate this experiment on your machine. It’s amazing to watch, it surprises me every time I re-run it.

Advertisements

Writing Express Middleware to Modify the Response

I recently had a need for some Express middleware that would track any change to a variable, and send the details of any changes in the response, but only if the response is JSON data. This turned out to be rather more interesting delve into ExpressJS than I expected, and I thought the details of it were worth a post detailing how to do it, and my findings.

The first thing you notice when writing Express middleware functions is that they take three arguments (I’m skipping error-handling middleware deliberately), the request, the response and a next() function that triggers the next step in the processing chain. The next function doesn’t typically take any arguments, instead you’re expected to modify the request and response objects to expose or capture any changes you want.

This post will show you how to capture any changes to a variable (we’re going to pretend all our users are playing a game and we have a leader-board), we want to track any changes that happen during the request and report both the changes and the current state of the variable in every response. I’m going to assume some other middleware has injected a user property onto the request. First off, this is what the code will look like:

const leaderboard = require('./leaderboard');
function leaderboardTracking(req, resp, next) {
  const user = req.user;
  const startingPosition = leaderboard.getUserPosition(user);
  const json_ = resp.json; // capture the default resp.json implementation

  resp.json = function(object) {
    const endPosition = leaderboard.getUserPosition(user);
    object['leaderboard_info'] = {
      'delta':    endPosition - startPosition,
      'position': endPosition,
      'score':    user.score
    };

    json_.call(resp, object);
  };

  next();
}

So in this example we swap out the json function with our own delegate implementation, but you’ll notice we leave the send function alone. The send function will delegate to the json function if it’s given a plain JavaScript object, and json in-turn uses send after stringifying the object.

You’ll also notice that the code doesn’t just invoke the captured json_ function, it uses the call function and specifies the response as this. The json function in Express expects to be invoked within the context of the response object, so we need to keep it that way.

That’s it really, it’s not a terribly complicated pattern, but it can be extremely powerful because it bounds the request / response cycle end-to-end.

BigDecimal and your Money

I often see Java developers attempting to use the BigDecimal class to store monetary values for financial applications. This often seems like a great idea when you start out, but almost always comes back as a flesh-eating zombie intent on devouring your entire time some time later on. The BigDecimal class is designed around accuracy and has an almost infinite size. However: this choice will almost always come back to bite you, or someone else attempting to find a minor bug later on. It’s an especially bad idea when it comes to banking applications. So why is BigDecimal not well suited to storing monetary values then? For one thing: it doesn’t behave in a manner that is practical for financial systems. While this statement flies in the face of everything you’ve probably been taught about this class, it’s true. Read-on and I’ll tell you why.

Theres more numbers in there than you think!

A BigDecimal is not a standard floating point number. Instead: it’s a binary representation of a number. This means: 0.0 != 0.00. While this doesn’t seem like a problem at first: I’ve seen it cause no-end of strange little bugs. The only way to accurately determine whether two BigDecimal objects have an equal value is by using the compareTo method. Try these two little unit tests:

@Test
public void testScaleFactor() {
    final BigDecimal zero = new BigDecimal("0.0");
    final BigDecimal zerozero = new BigDecimal("0.00");

    assertEquals(zero, zerozero);
}

@Test
public void testScaleFactorCompare() {
    final BigDecimal zero = new BigDecimal("0.0");
    final BigDecimal zerozero = new BigDecimal("0.00");

    assertTrue(zero.compareTo(zerozero) == 0);
}

This technique works when you’re in control of the data and the comparison, but it breaks when you want to put a BigDecimal object into most other Java data-structures. I’ve actually seen someone use a BigDecimal as a key to a HashMap, which of course didn’t work. The solution in this case was simple: change the HashMap for a TreeMap and things were happy. However it won’t always be this simple.

They’re true high precision structures.

This doesn’t just mean that they are precise, it also means that they won’t run any calculation that wouldn’t result in a representable answer. Take the following code snippet as an example:

@Test
public void testArithmatic() {
    BigDecimal value = new BigDecimal(1);
    value = value.divide(new BigDecimal(3));
}

Primitive numeric types would just swallow this and represent the 0.3* as best they could, while a BigDecimal throws an ArithmeticException instead of attempting to represent a recurring number. In some cases getting an error will be desirable, but I’ve actually seen someone resolve the ArithmaticException like this:

try {
    return decimal1.divide(decimal2);
} catch(ArithmaticException ae) {
    return new BigDecimal(decimal1.doubleValue() / decimal2.doubleValue());
}

Yes folks, unfortunately I’m quite serious here. This is the sort of bug introduced by an error occurring, computations stop running, and someone adds a “hack” to just “make it work quickly and we’ll fix it later“. It’s a total disaster, but I see it far to often.

They don’t play nice with Databases.

According to the JDBC spec database drivers implement a getBigDecimal, setBigDecimal and updateBigDecimal functions. They seem like a great idea, until you ponder that your database may not have a suitable storage type for these values. When storing a BigDecimal in a database, it’s common to type the column as a DECIMAL or REAL SQL type. These are both standard floating-point types, with all the rounding errors that implies. They are also limited in capacity and will often overflow or cause a SQLException when attempting to store very large BigDecimal values.

The only practical solution which will keep all the BigDecimal functionality and accuracy in a database is to type the amounts a BLOB columns. Try to imagine the following table structure if you will:

CREATE TABLE transactions (
    initial_date DATETIME NOT NULL,
    effective_date DATETIME NOT NULL,
    description VARCHAR(30) NOT NULL,
    source_id BIGINT NOT NULL,
    destination_id BIGINT NOT NULL,
    in_amount BLOB NOT NULL,
    in_amount_currency CHAR(3) NOT NULL,
    effective_amount BLOB NOT NULL,
    effective_amount_currency CHAR(3) NOT NULL,
    charge_amount BLOB NOT NULL,
    tax_amount BLOB NOT NULL
);

That required four different BLOB columns, each one of which will be stored outside of table space. BLOB objects are very expensive both to store, and to work with. Each one often uses it’s own database resources (much like an internal cursor) to read or write the value. This translates to much more time and network usage between your application and it’s database. To add to the misery a BLOB is generally not readable by a SQL tool, one of the major reasons for sticking with a SQL database is that it can be managed from outside of your application.

Performance.

This is often raised as an issue, but ignored in favor of “accuracy”. The performance of BigDecimal is often considered “good enough” for general computing, and it’s fine if you want to add tax to an item every once in a while, but consider the number of interest calculations per month a moderate sized bank do. This may seem like an extreme case, but if your application ran a simple shipping and tax calculation for items on an online store in a JSP you’ve got effectively the same problem. In a very simple multiplication test BigDecimal performed over 2300 times slower than a simple long value. While this may only be milliseconds per mutation, a performance-factor of this size very quickly adds up to more computational time than is actually available to the system.

Also remember that BigDecimal (like most Number subclasses) are immutable. That means every calculation requires a copy of the existing BigDecimal. These copies are generally cleaned away by the eden-space collector (and G1 is very good at handling them), but when you put such a system into production it leads to a massive change in your heap requirements. Your BigDecimal objects must be allocated in such a way that a minimum number of them survive a garbage collection, the memory requirement of such a space quickly spirals out of control.

To add to the performance argument: the compareTo method is quite a bit slower than the equals method, and gets significantly slower as the size of the BigDecimal increases.

A Cure to BigDecimal Woes:

A standard long value can store the current value of the Unites States national debt (as cents, not dollars) 6477 times without any overflow. Whats more: it’s an integer type, not a floating point. This makes it easier and accurate to work with, and a guaranteed behavior. You’ll notice that several different behaviors in BigDecimal are either not well defined, or have multiple implementations. That said: depending on your application you may need to store the values as hundredths or even thousandths of cents. However this is highly dependent on your application, and theres almost always someone who can tell you exactly what unit the business works in. Bare in mind also that there are often de-facto (or even mandated) standards which exist between businesses about what unit of money they deal in, using more or less precision can lead to some serious problems when interfacing with suppliers or clients.

The mechanism I generally try to use is a custom-built MoneyAmount class (each application has different requirements) to store both the actual value, and it’s Currency. Building your own implementation opens the opportunity to use factory methods instead of a constructor. This will allow you to decide on the actual data-type at runtime, even during arithmetic operations. 99% of the time, an int or long value will suffice – when they don’t the implementation can change to using a BigInteger. The MoneyAmount class also enables you to define your own rounding schemes, and how you wish to handle recursive decimal places. I’ve seen systems that required several different rounding mechanisms depending on the context of the operation (currency pairs, country of operation and even time of day). For an example of this kind of factory discussion: take a look at the source-code for the java.util.EnumSet class. Two different implementations exist: the RegularEnumSet class uses a long to store a bit-set of all the selected constants. Given that very few enum values have more than 64 constants this implementation will cover most cases, just like a long will cover most requirements in a financial system.

Summary

This post is to warn people who are busy (or about to start) writing a system that will run financial calculations and are tempted to use BigDecimal. While it’s probably the most common type used for this purpose in the “enterprise” world, I’ve seen it backfire more times than I care to recount. My advise here is really to consider your options carefully. Taking shortcuts in implementation almost always leads to pain in the long-run (just look at the java.util.Properties class as an example of this).

Unit Testing with Mock Objects and EoD SQL

Introduction

Unit Testing has become one of the corner-stones of good software development (it has been such for quite a long time actually). However writing a Unit Test that interacts with database code (at any level) can be very challenging. The main problem being: your data should be in a “known” state when the Unit Test starts running. In the past many approaches to this problem have been taken, such as: using an in-memory database; or DbUnit. Each approach has it’s up-sides and it’s down-sides (I won’t be going into them here).

To help your unit testing along EoD SQL is growing it’s own mocking extension (currently only in Subversion however). The EoD-Mock project allows you to build mock implementations of your database connection code without any external configuration. Thats right: no dependency injection; no JNDI; no factories; nothing!

How does it work?

If the EoD-Mock JAR file is on the class-path, EoD SQL will automatically look for mock implementations of your Query interfaces instead of generating a real implementation. For example, take a simple UserQuery interface:

public interface UserQuery extends BaseQuery {
    @Select("SELECT * FROM users WHERE email = ?1")
    User selectByEmail(String email);

    @Update(sql = "INSERT INTO users (email, username, birth_date) "
    + "VALUES(?{1.email}, ?{1.username}, ?{1.birthDate})",
    keys = GeneratedKeys.RETURNED_KEYS_FIRST_COLUMN)
    User insert(User user);

    @Select("SELECT * FROM users")
    DataSet<User> selectUsers();
}

To create a Mock of this interface using EoD-Mock all you need to do is write an implementation in the same package:

public class UserQueryMock extends AbstractMockQuery implements UserQuery {

    private final List<User> users = new ArrayList<User>();

    public UserQueryMock() {
        insert(new User("joe.bloggs@nowhere.com", "Joe Bloggs", new Date(83, 3, 6)));
        insert(new User("jeff@jeffswebsite.com", "Jeff Site", new Date(76, 8, 23)));
        insert(new User("logan@murkmurk.com", "Logan Sleep", new Date(90, 4, 1)));
    }

    public User selectByEmail(final String email) {
        for(final User user : users) {
            if(user.getEmail().equals(email)) {
                return user;
            }
        }

        return null;
    }

    public User insert(final User user) {
        final long id = users.size();

        final User clonedUser = new User(
                user.getEmail(),
                user.getUsername(),
                user.getBirthDate());

        clonedUser.setId(id);

        users.add(clonedUser);

        final User idUser = new User(null, null, null);
        idUser.setId(id);

        return idUser;
    }

    public DataSet<User> selectUsers() {
        return new MockDataSet<User>(users, false, true);
    }

}

Yup, it’s really as simple as that. Now if you ask EoD-SQL for an instance of UserQuery (ie: QueryTool.getQuery(UserQuery.class)): instead of generating an implementation, it will create an instance of UserQueryMock and return that.

How much does eod-mock take care of?

  • EoD-Mock will self-register as a QueryFactory with EoDSQL (but only under Java 6 and higher) if it’s on the classpath
  • A “default” DataSource is provided automatically. The provided implementation throws exceptions instead of providing database access
  • An AbstractMockQuery class is provided to take care of the methods declared in BaseQuery
  • A MockDataSet is provided, and will attempt to behave like a real DataSet object
  • QueryTool.getQuery will automatically return mocked query objects, meaning: no changes to your data-access layer

Current State

EoD-Mock is currently only available in the Subversion repository, but will be included in the next release of EoD SQL. There is no support currently for the DataIterator class, but that will no-doubt come very soon.

EoD SQL Applied – Part 5 / 5 (GWT Applications)

The Dreaded “Not Serializable” Problem

GWT turns all of your Java code into JavaScript, but it also obfuscates everything. With this in mind, it makes serialization a bit more complex than usual. GWT generates a serializer and deserializer for each class that could be transported across the wire to an RPC service. The difficulty comes in knowing which types had code generated, and which didn’t. GWT solves this problem for itself with the Serialization Policy file, where the compiler lists all of the classes that the client code will know how to deserialize.

This however leads to another problem: what happens when something unexpected gets in the way. Hibernate is the most used, and thus most complained about when it comes to Serialization problems. Hibernate turns any Collection object into a special “lazy” implementation that will only load your data when you ask for it. All very fine and well for a server bound application, but a GWT application needs all that data up front for serialization. When GWT comes to sending that List<Message> to the client, it chokes. It knows how to serialize an ArrayList, and LinkedList (since you worked with them on the client side), but a Hibernate List or PersistentCollection is a totally unknown type, so it’s not in the Serialization Policy, so the server side throws an Exception at you.

So how does EoD SQL help with these problems? Read on to find out! 😉 Read the rest of this entry »

EoD SQL Applied – Part 4 / 5 (JavaScript)

JavaScript vs. Web Applications

So far in this series we’ve discussed using DataSets for Swing applications and DataIterators for web-applications. Why would I now bring in JavaScript as something outside of “web-application”? JavaScript applications have very different requirements to a normal web-application. Where a normal web-application has little ability to do things like preload data (like the next page), a JavaScript application may (for example) download the entire data-set and then display it in pages. This next section is about binding to JSON for JavaScript applications.

First thing to remember here is that an EoD SQL DataSet is a List and thus compatible with the Collections API. For this example we’re going to be working with the outstanding GSON API from our friends at Google. Our objective here is to minimize the amount of time spent between the Database and pushing the data to the client. Because GSON doesn’t appear to support Iterable object out-of-the-box, we’re going to start off using a DataSet.
Read the rest of this entry »

EoD SQL Applied – Part 3 / 5 (JSP / Servlets)

Static Data Display

In a Swing application with a direct connection to a database, it makes sense to leave the database to do much of the heavy lifting. The Swing client can keep a minimum amount of data in memory, while holding a scrollable Result Set open on the database (fetching more of the data as required). In a web application on the other hand, things are a little more complex. For one thing, your database isn’t exposed to the any part of the network; for another: your clients have no ability to keep Result Sets open; and finally: you generally are working with much higher loads than a Swing application.

EoD SQL has many different approaches to loading data from the database. We’ve already looked at DataSet objects, which remain connected to the database and work well with scrollable, cursor backed, Result Sets. DataSets are (in a way) a leftover from the origional EoD API from Java6-beta (where they were the only way to fetch objects from the database). In this post we’ll take a look at an EoD SQL idea: DataIterators.

Read the rest of this entry »