Posts

Showing posts from January, 2012

"Java Sucks" revisited

Overview An interesting document on Java's short comings (from C developer's perspective) was written some time ago (about 2000? ) but many of the arguments issues are as true (or not) today as they were ten years ago. The original Java Sucks posting. Review of short comings Java doesn't have free(). The author lists this as a benefit and 99% of the time is a win. There are times when not having it is a downside, when you wish escape analysis would eliminate, recycle or free immediately an object you know isn't needed any more (IMHO the JIT / javac should be able to work it out in theory) lexically scoped local functions The closest Java has is anonymous methods. This is a poor cousin to Closures (coming in Java 8), but it can be made to do the same thing. No macro system Many of the useful tricks you can do with macros, Java can do for you dynamically. Not needing a macro system is an asset because you don't need to know when Java will give you the same

Demonstrating when volatile is required

Overview In many cases volatile is required when you need a guarantee about visibility of changes between threads. i.e. All threads see a consistent view of the same field. Demonstrating a consistent failure when you don't use volatile is tricky, and likely to be platform specific. An example The following example show that each thread starts by flipping the value and then stops as each thread has a different view of the field value This works on Java 7 update 2 on Centos 5.7 (x64). Even incidental change to the code, change the behaviour showing how brittle the example is. I would be interested if others can reproduce this behaviour The code public class RequiresVolatileMain { static boolean value; public static void main(String... args) { new Thread(new MyRunnable(true), "Sets true").start(); new Thread(new MyRunnable(false), "Sets false").start(); } private static class MyRunnable implements Runnable { p

Another Shifty Challenge

Overview Shifting has lots of edge cases. Some particular to Java. Over shifting In C the expression n << 64 and n >> 64 would always be 0, but in Java it will always be n This is because the shifted value is mod'ed by the number of bits. A puzzle If the following program for (int i = -200; i < 200; i++) if (i >>> i == 1) System.out.print(i+" "); prints -193 -161 -129 -97 -65 -33 -1 37 70 102 135 167 199 What do you get if you change the type to long ? See if you can work it out without running the code.

Shifting Challenge

Overview Using shift in Java and some surprising edge cases. Getting the sign For the following program, what is the values for n so that I can change the type of x without having to change the code. // sign is 1 if negative and 0 if non-negative long sign = x >>> n; There is a value you can replace n such that you don't need to know the type of x Similarly, I want to shift the lowest bit to be the highest without knowing what type I am shifting // sign is MIN_VALUE if odd otherwise 0 long sign = x << n; For bonus points, write formula for all the possible solutions of n (there is more than one) Is a power of two How do you determine an integer is a power of 2. This is a fairly common interview question. Its pretty hard to figure out in an interview I imagine. To save you googling, you can write this in C with x&&!(x&(x-1)) In Java, you can write this using just 0 ~ - & == != . Complete this expression using those operators long

Unsigned Challenge

Overview Its easy to assume that because Java doesn't support unsigned primitives that you need a complex wrapper to using unsigned numbers. The challenge Modify the following class which has been written to use signed int as unsigned value. The starting code works for signed values. You need to change the methods so it treats them as unsigned 32-bit int values. The aim is to add/change a minimum of lines. (You can't change the tests or turn them off) public enum Unsigned {; public static int add(int i, int j) { return i + j; } public static int subtract(int i, int j) { return i - j; } public static int multiply(int i, int j) { return i * j; } public static int shiftLeft(int i, int n) { return i << n; } public static int shiftRight(int i, int n) { return i >> n; } public static int parseUnsignedInt(String text) { return Integer.parseInt(text); } public

Java Thread Affinity support for ExecutorService

Overview The Java Thread Affinity version 1.4.1 library has support for the concurrency library through an AffinityThreadFactory. This follows my previous article on HyperThreading support in the library which give mroe detail on what it does and how it works. Example In the AffinityThreadFactoryMain example, private static final ExecutorService ES = Executors.newFixedThreadPool(4, new AffinityThreadFactory("bg", SAME_CORE, DIFFERENT_SOCKET, ANY)); public static void main(String... args) throws InterruptedException { for (int i = 0; i < 12; i++) ES.submit(new Callable () { @Override public Void call() throws InterruptedException { Thread.sleep(100); return null; } }); Thread.sleep(200); System.out.println("\nThe assignment of CPUs is\n" + AffinityLock.dumpLocks()); ES.shutdown(); ES.awaitTermination(1, TimeUnit.SECONDS); } by changing the Thre

Java Thread Affinity support for hyper threading.

Image
Overview A benefit of hyper-threading is the ability to support more threads without incurring the overhead of context switches. If your threads spend a high proportion of their time waiting for resources e.g. busy waiting on a data source, accessing main memory or waiting for short periods of time for IO, hyper threading can improve performance at little cost. However, hyper threading can impact performance when the two threads on the same core start competing for resources, such as the FPU, Level 1 cache, or CPU pipeline. For these reasons, hyper-threading is often turned off in high performance systems. A solution to get the best of both worlds The Java Thread Affinity version 1.4 library attempts to get the best of both worlds, by allowing you to reserve a logical thread for critical threads, and reserve a whole core for the most performance sensitive threads. Less critical threads will still run with the benefits of hyper threading. Example Say you have a system e.g. an

Surprising results of autoboxing

Overview There are a number of surprising consequences of auto-boxing. Some are more widely known than others. Most of them are due to the effect of caching of some auto boxed objects. == and equals may or may not match If you run the program AutoboxEqualsMain with default options. All Boolean are cached. All Byte are cached. The first auto-boxed char is 0 and the last is 127 The first auto-boxed short is -128 and the last is 127 The first auto-boxed int is -128 and the last is 127 The first auto-boxed long is -128 and the last is 127 No Float are cached. No Double are cached. For those that know that == compares references , for Integer or any Object type. Run the program again with -XX:+AggressiveOpts on Java 7 and you get almost the same result. All Boolean are cached. All Byte are cached. The first auto-boxed char is 0 and the last is 127 The first auto-boxed short is -128 and the last is 127 The first auto-boxed int is -128 and the last is 20000 The first auto-boxed long

Java Thread Affinity supports groups of threads.

Overview The Java Thread Affinity Library version 1.3, supports assigning groups of threads together by Socket, Core, or a custom strategy. Determining the grouping of threads The following Affinity Lock binding example , shows how you can choose to take either different sockets or cores, or share the same sockets or cores. It creates a thread lock for "main". For the reader and writer threads it tries to get a different socket or core to "main", and reserve a cpu on the same core or socket as each other. AffinityLock al = AffinityLock.acquireLock(); try { // find a cpu on a different socket, otherwise a different core. AffinityLock readerLock = al.acquireLock(DIFFERENT_SOCKET, DIFFERENT_CORE); new Thread(new SleepRunnable(readerLock), "reader").start(); // find a cpu on the same core, or the same socket, or any free cpu. AffinityLock writerLock = readerLock.acquireLock(SAME_CORE, SAME_SOCKET, ANY); new Thread(new SleepRun

Generating every combination without duplicates

Overview Generating every combination where there is no duplicates is pretty simple. Handling the situation where there can be more than one value which is the same is trickier. The problem In this problem you have a list, with duplicates. e.g. [1, 1, 2, 3, 3, 3] Find all the combinations of this list, is a way which doesn't create any duplicates. e.g. if you swap the 1s around, its the same list. You can do this with brute force by creating every combination and adding them to a Set to remove duplicates. The Set grows with the number of solutions. You can avoid the need to do this, by using a strategy to generate all possible lists which don't result in duplicates. A solution When building a collection to describe the problem all elements which are the same are equal and the order doesn't matter, only the number of times that element appears. e.g. 2 of 1, 1 of 2, 3 of 3. This collection can also be used to determine how many of each time is still left. For the

Project Euler

Project Euler has a good list of interesting puzzles to solve for any language. I worked on a quite a few at one point but haven't for a while until someone mentioned Problem 303 I suggest you try a few if you haven't already Project Euler Problems . For extra difficulty you can try to make the program shorter, or faster. e.g. My solution to Problem 303 runs in 1.524 seconds solving all values (without guessing) When you solve a problem you can look at how some people solved the problem in different languages which is pretty cool IMHO.

Generic class names to avoid

Overview Java (Oracle Java update 2) has many classes with the same generic name. To avoid further confusion, I suggest avoiding these names if you can. Most repeated The following class names are repeated, 19 Handler, 16 Messages, 13 Util, 10 Element, 8 Attribute, 7 SecuritySupport, 7 Node, 6 Provider, 6 Header, 6 FactoryFinder, 6 Document. 5 SOAPBinding, 5 Repository, 5 Ref, 5 ORB, 5 Name, 5 Constants, 5 Connection, 5 Comment, 5 Binding, 5 Attributes, This excludes the Apache XML library which repeats many names. If you include these libraries there are 26 classes called SecuritySupport. Four times Window, Version, Utility, Timer, Text, State, Signature, ServiceName, ServiceConfigurationError, Service, ResourceLoader, Queue, Policy,

Top Java Article of 2011

If you google Top Java Article of 2011 the first site it matches is an interesting web site Top 20 Java Websites and the first article is a mirror an article from this blog How to get C like performance in Java . BTW: If you do it multiple times the order changes sometimes. Perhaps it hits different servers? I am sure its just a matter of using the right combination of words to search for, but I think its pretty cool. ;)

String.valueOf(int) vs "" + int

Overview There are a number of reason prefer either int i = ... String s = "" + i; String s = String.valueOf(i); These include simplicity clarity efficiency performance Personally I prefer efficiency for the developer as the performance difference is very, very small. IMHO, "" + i is also simpler and clearer, but that is a matter of taste. Comparing the performance difference public static void main(String... args) throws IOException { for (int i = 0; i < 3; i++) { long svo = perfStringValueOf(); long qqp = perfQuoteQuotePlus(); System.out.printf("String.valueOf took an average of %.3f us and \"\"+ took an average of %.3f us%n", svo / 1e3, qqp / 1e3); } } private static long perfStringValueOf() { long start = System.nanoTime(); final int runs = 100000; String s; for (int i = 0; i < runs; i++) { s = String.valueOf(i * i); // ensure s is not optimised away

An odd case of initialization

Overview You might assume that once a variable has been initialized it stays that way. However, the javac compiler, treats a variable as initialized only when it can determine a variable has been set, and exception handling can confuse the compiler. But I know its initialised because I used it In the following example, a variable is treated as initialized but after a catch block, the compiler isn't sure, and the variable can assigned again and used later. int a; try { a = 1; // a is initialised and can be read. System.out.println(a); // compiles ok. } catch (RuntimeException ignored) { } // a is not considered initialised as the compiler // doesn't know the catch block couldn't be thrown before a is set. System.out.println(a); // Variable 'a' might not have been initialized a = 2; // a is definitely initialised. System.out.println(a); // compiles ok. The problem here is that you know that the variable cannot throw an exception before the variabl

Java Puzzler, double chars

A teaser which uses char and double The following compiles and produces an output. Can you explain why? char ch = 'A'; ch *= 1.5; System.out.println(ch); // prints 'a' Here is a hint for a simpler example. byte b = 100; b /= 2.5; System.out.println(b); // prints 40

Regex vs IndexOf in Java.

Overview The author of these articles Are C# .Net Regular Expressions Fast Enough for You? and .Net Regex: Can Regular Expression Parsing be Faster than XmlDocument or Linq to Xml? recently pointed out to me that he had found that Regular expressions were at least as fast or faster than the alternatives in C#. However it has been my experience that regular expressions in Java were slower. It is hard for me to say why this might be different in Java and C# or even if these are fair comparisons but here is what I found in Java. Searching XML for the start of a field This test searches for the expression " \\s* " in short section of text. Performing 1 loops, regex took 323.389 us and indexOf took 73.026 us on average, ratio=4.4 Performing 10 loops, regex took 61.513 us and indexOf took 42.480 us on average, ratio=1.4 Performing 100 loops, regex took 84.899 us and indexOf took 8.134 us on average, ratio=10.4 Performing 1,000 loops, regex took 16.307 us and indexOf took 5.