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 !

Thursday, April 30, 2009

Struggling with Java Generics

The idea of Java generics looks straightforward. Really, templates exist in C++ for years, and one doesn't expect too much trouble with much simpler syntax of Java generics. But devil is in details. The major caveat is verifiability requirement.

Look at this [oversimplified] C++ design:

// Class that creates copies of objects of
// given typename T
template<typename T>
class Copier {
private:
    T* t;
public:
    Copier() : t(NULL) {}
   
    T* getCopy() {
        if(t == NULL) {
            t = new T();
        }
        return t->createCopy();
    }
};
   
// Class that is capable to create
// copies of objects of more than one type;
// it uses Copier as a building block
template<typename A, typename B>
class CopyMaster {
private:
    Copier<A> copierA;
    Copier<B> copierB;
public:
    A* getA() {
        return copierA.getCopy();
    }
    B* getB() {
        return copierB.getCopy();
    }
};
   
// Two concrete classes Dolly and Lizard
// can create copies of themselves and are
// ready to be used in Copier<>
class Dolly {
public:
    Dolly* createCopy() {
        return new Dolly();
    }
};
   
class Lizard {
public:
    Lizard* createCopy() {
        return new Lizard();
    }
};
   
   
int main(int argc, char* argv[]) {
    // This particular instance of CopyMaster
    // can create copies of sheep and reptiles
    CopyMaster<Dolly, Lizard> copyMaster;
    Dolly* concrete1 = copyMaster.getA();
    Lizard* concrete2 = copyMaster.getB();
    return 0;
}

The challenge is to achieve the same functionality with Java generics.

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.

Thursday, April 23, 2009

Posting Code

This blog is about computers, programming and alike. So its essential for me to be able to post source code in descent form. In the case of Visual Studio the answer appeared obvious. My idea was to copy code to Windows clipboard, paste into wordpad, save as Rich Text Format file (*.rtf), convert to html and paste into blog editor.

The step that almost failed was converting from rtf to html. All free converters I was able to spot on the Web miserably failed. I even don't want to give links to the suckers. Well, I said almost. One converter worked good for me. The online one. Of course, its a hassle to use online stuff with all verifications etc., but for me its better than inferior quality of conversion. Check the quality for yourself:

// This is a comment
int main(int argc, char* argv[])
{
    cout << "Hello, RTF 2 HTML!" << endl;
    return 0;
}
   

I copied the html code from Firefox's View->Page Source window.
So, if you are curious, find the link to the converter below:
RTF to HTML Online
Another downside of the converter - bloating size of the resulting html. In the example above size changed from 516 bytes in rtf file to 1,698 bytes in the converted html file.

Wednesday, April 22, 2009

Search in Jars

Does one need a specialized application to search jar files for certain class or function? Just before recently I thought it was true. I found some applications like this on the Web and I decided to download some of them. Nevertheless, it turned out that all downloads were blocked in my office environment. But any coin has two sides, so it was opportunity for me to come up with simple pair of scripts that does the trick.

//---------------------------- file searchJars
#!/bin/bash
CACHE=~/bin/listOfJars_

if [ ! -f $CACHE ]
then
 cacheJars $CACHE
fi

for file in $(cat $CACHE) ; do
 found=$(jar tf $file | grep $1)
 if [ "$found = "" ]
 then
  continue
 fi
 echo ============= FOUND ============
 echo $file
 echo $found
done
//---------------------------- file searchJars end

//---------------------------- file cacheJars
#!/bin/bash
CACHE=~/bin/listOfJars_

if [ "$1" != "" ]
then
 CACHE=$1
fi

find ~ -name *.jar > $CACHE
//---------------------------- file cacheJars end

The scripts are just bare bones, not foolproof, they don't suggest help or prevent incorrect usage. You can add this stuff yourself.
This is what you do: create folder bin in your home directory, create files searchJars and cacheJars with above content there. Don't forget to make them executable with
 chmod +x <filename>
Then run
 ~/bin/searchJars SomeMethod

First time the execution will be slower because of caching all jars' into the list. Next time the step will bi omitted. To refresh the cache run
 ~/bin/cacheJars
without parameters.