Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Wednesday, July 29, 2009

Binary literals in Java

Integer (byte, short, int or long) literals in Java can be expressed using one of the following three formats

int n08 = 052;
int n10 = 42;
int n16 = 0x2A;

Here all three variables represent the same number. There is no out-of-the-box binary presentation. Nevertheless, it is desirable sometimes to specify constants in easy readable binary form, for example for bit masks.

The answer from Ed Swangren works fine.

int n02 = Integer.parseInt("101010", 2);

Here is another example:
public final static long mask11 =
Long.parseLong("00000000000000000000100000000000", 2);

I used long instead of int and added the modifiers to clarify possible usage of the presentation as a bit mask. There are, though, two inconveniences with this approach.
  1. The direct typing of all those zeroes is error prone

  2. The result is not available in decimal or hex format at the time of development

I can suggest alternative approach
public final static long mask11 = 1L << 11;

This expression makes it obvious that the 11th bit is 1 (count starts from 0, from the right to the left); and when you hover mouse cursor, the tooltip
long YourClassName.mask11 = 4096 [0x1000]

appears in Eclipse. You can define more complicated constants like:
public final static long n02 = mask05 | mask03 | mask01;

or explicitly
public final static long n02 = (1L<<5)|(1L<<3)|(1L<<1);

The value of the variable n02 will still be available in Eclipse at development time.

Thursday, July 23, 2009

Homemade recipe

This is another example of how simple "homemade" approach significantly outperforms patented generic methods. How often you needed to convert byte array into String object and vice versa? The recommended methods always require the name of Charset. Since in my case the charset is always UTF-8, I hardcoded it.
When converting from byte array to String, something like following can be used:
final static String b2s_recommended(byte[] bb) {
    try {
        return new String(bb, 0, bb.length, "UTF-8");
    } catch(Exception ex) {
        throw new RuntimeException(ex.getMessage());
    }
}
   
   

When converting from String to byte array something like following can be used:
final static byte[] s2b_recommended(String s) {
    try {
        return s.getBytes("UTF-8");
    } catch(Exception ex) {
        throw new RuntimeException(ex.getMessage());
    }
}
   
   

Corresponding "homemade" methods that don't pretend to be generic, can look like following:
final static String b2s_homemade(byte[] bb) {
    char[] cc = new char[bb.length];
    for (int i = 0; i < bb.length; ++i) {
        cc[i] = (char) bb[i];
    }
    return new String(cc);
}
   
final static byte[] s2b_homemade(String s) {
    byte[] bb = new byte[s.length()];
    for (int i = 0; i < bb.length; ++i) {
        bb[i] = (byte) s.charAt(i);
    }
    return bb;
}
   

On my computer homemade b2s outperformed recommended one with factor of 4.2 . For the s2b the performance bust was 6.0 !

Wednesday, April 29, 2009

Shariah Law and java.util.TimerTask

The java.util.Timer makes the following promise: This class scales to large numbers of concurrently scheduled tasks (thousands should present no problem). Fine, I like it. So I wanted to arrange a timer to take care of thousands of not very sensitive to real-time guarantees tasks. The only concern was performance, so I created an object pool to avoid creation of new java.util.TimerTask objects every time I need them. The intention was to reuse canceled and executed tasks from the pool. The quirk was that the Timer implementation rejects such Task objects! When I looked at the source code of Timer, it turned out that java.util.Timer.sched(TimerTask task, long time, long period) method rejects Task if it is not in VIRGIN state. Is it Shariah Law based decision? And there is no way to change this idiosyncrasy by deriving from Task, because state data member has package visibility and no setter.

Isn't it a good example of how politics affects software design?

Sunday, April 26, 2009

Legend Confirmed

There is number of facts circulating in the form of urban legends. And there are sites devoted to these facts. The sites discuss the matters and most of the time disprove the statement made by the legend. I think many statements in programming can be classified as legends of the kind. That's why before selecting a solution to some problem it makes sense to double check facts that can affect your decision.

One of the commonly admitted facts I knew for a long time was that reflection in Java is slow. I believed the fact in general, but when writing my own class that needed generic construction of an object I decided to test the legend. My hope was that for a task as simple as using of default constructor call to new cannot be much better than call to class.newInstance(). Here is my test program (I took some precautions to avoid optimizing out creation of the objects from the loop):
import java.util.GregorianCalendar;
public class Console {
    static class Foo {
        long l;
        double d;
        String s = "foo";
        Foo() {
            l = new GregorianCalendar().getTimeInMillis();
            d = (double)(l * l);
        }
    }
    public static void main(String[] args) {
        try {
            long l1 = new GregorianCalendar().getTimeInMillis();
            double sum = 0;
            Class<Foo> clazz = Foo.class;
            for(int i = 0; i < 1000000; ++i) {
                Foo foo = (Foo) clazz.newInstance();
                sum += foo.d;
                foo = null;
            }
            long l2 = new GregorianCalendar().getTimeInMillis();
            System.out.println("" + sum + ": " + (l2-l1));
            sum = 0;
            for(int i = 0; i < 1000000; ++i) {
                Foo foo = new Foo();
                sum += foo.d;
                foo = null;
            }
            l1 = new GregorianCalendar().getTimeInMillis();
            System.out.println("" + sum + ": " + (l1-l2));
        } catch (Throwable e) {}
    }
}
   


Here is the result: I was wrong. Creation of 1,000,000 objects on my computer took ~1,700 millis with the call to class.newInstance() and ~1,050 millis with the call to new. Conclusion: some legends can be trusted. But you never know which.