Posts

Showing posts from December, 2012

Can synchronization be optimised away?

Overview There is a common misconception that because the JIT is smart and synchronization can be eliminated for an object which is only local to a method that there is no performance impact. A test comparing StringBuffer and StringBuilder These two classes do basically the same thing except one is synchronized (StringBuffer) and the other is not. It is also a class which is often used in one method to build a String.  The following test attempts to determine how much difference using one other the other can make. static String dontOptimiseAway = null; static String[] words = new String[100000]; public static void main(String... args) {     for (int i = 0; i < words.length; i++)         words[i] = Integer.toString(i);     for (int i = 0; i < 10; i++) {         dontOptimiseAway = testStringBuffer();         dontOptimiseAway = testStringBuilder();     } } private static String testStringBuffer() {     long start = System.nanoTime();     StringBuffer sb = new StringBuffer();

Local variables inside a loop and performance

Overview Sometimes a question comes up about how much work allocating a new local variable takes.  My feeling has always been that the code becomes optimised to the point where this cost is static i.e. done once, not each time the code is run. Recently Ishwor Gurung suggested considering moving some local variables outside a loop. I suspected it wouldn't make a difference but I had never tested to see if this was the case. The test. This is the test I ran public static void main(String... args) {     for (int i = 0; i < 10; i++) {         testInsideLoop();         testOutsideLoop();     } } private static void testInsideLoop() {     long start = System.nanoTime();     int[] counters = new int[144];     int runs = 200 * 1000;     for (int i = 0; i < runs; i++) {         int x = i % 12;         int y = i / 12 % 12;         int times = x * y;         counters[times]++;     }     long time = System.nanoTime() - start;     System.out.printf("Inside: Average loop

Object resurrection

Overview After an object which overrides finalize() is collected it is added to a finalization queue to be cleaned up after calling the finalize() method of each object.  By what happens if you resurrect the object? When is finalize called? The finalize method is called by a single threaded system task which calls this method for each object which has been collected. Note: the nodes in the finalization queue are objects also have finalize() methods notionally. Objects cannot be cleaned up until the GC after they have been finalized. Most objects (including the node in the finalization queue) don't overriden finalize() and so the GC is smart enough to detect this and not add them to the queue. These obejcts can be cleaned up immediately. If you override the method, even with an empty one, it makes a difference. What about resurrected objects? In the finalize() method, you can resurrect the object by giving making something point to it. e.g. a static collection.  This ob

Over one million page views

A some point recently I got more than one million pages views, including mirror sites. Thank you all for your interest and encouragement.

A use for overflow

There is simple, but expensive problem in cryptography is Modular Exponentiation which can be written as Calculate y = ( p ^ n ) mod ( 2 ^ 32 ) where p is a prime number and n is a large integer. Using BigInteger You can use the obvious way using BigInteger. BigInteger answer = BigInteger.valueOf(prime)                               .pow(number)                               .mod(BigInteger.valueOf(2).pow(32)); This works, but is very expensive for large numbers.  This can take minutes/hours for large number. Fortunately BigInteger has a method which is useful in the situation. Instead of generating a very large numebr only to modulus back into a smaller one, it has a combined method called BigInteger modPow(BigInteger power, BigInteger mod)   This method is much faster and can take milli-seconds. Using Overflow If you look at the magic number 2^32 this appears to be an odd choice at first.  The trick is to realise this is the same as & 0xFFFFFFFFL or just

Performance of inlined virtual method invocations in Java

Overview One of the benefits of dynamic compilation it the ability to support extensive method inlining on virtual method code. While inlining the code improves performance, the code still has to check the type (in case it has changed since it was optimised) or select between multiple possible implementations. This leads to the question; how does having multiple implementations of a method, called via an interface,  impact performance. Benchmarking This benchmark tests a trivial method invoked as elements of a list.  It compares different numbers of classes in the list to see how it performs, but also varies the amount the loop is unrolled so that the number of possible classes is reduced. e.g. for a list of 12 different classes, in a repeating pattern, with out unrolling the method invocation could be to any of the 12 classes, but when the loop is unrolled to a degree of two, each call has only 6 possible classes (12/2). When unrolled to a degree of three, there is 4 possibl