Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Hubert Klein Ikkink (aka Mr.Haki) - Communications Officer
 Mr.Haki's JBuilder Jar #64
See Also: JBuilder Papers

Resource bundles
In Java it is pretty easy to "resource" hard-coded strings in an application. We store the strings in separate files and can so easily create different files for every language we want to support.
Standard Java APIs provide us with two different ways to store the hard-coded strings in resource bundle files:

The first option provides great flexibility, because we change the values without recompiling the application. The second option provides better performance. The Java source file with the key-value pairs needs to be compiled everytime a change occurs.

The JBuilder packages contain a third way to store the values of hard-coded strings:

com.borland.jb.util.ArrayResourceBundle

This class stores the values of keys in a String[] array object, but without the keys themselves. We can access the values by index. So the first value can be referenced by index 0, the second by index 1, ...
Because the values can be directly accessed the performance is very good. But there is a downside: it is difficult to maintain the file, because there is no direct (visible) connection between a key and its value.

Let's see a small example application, which shows all three ways to use resource files. We use the following resource files:

Each of these resource file contain 50 values (value1 ... value50), which correspond with 50 keys. In the ArrayResource class we don't specify keys, because we use the index in the array to access the values. When extending from the com.borland.jb.util.ArrayResourceBundle class we must override the following method: public Object[] getContents(), which simply return the array with the values.

We can test the performance of each of the resource solutions with a simple test application:

  package com.drbob42.jbjar.tip64;

  import java.util.ResourceBundle;
  import java.util.Enumeration;
  import com.borland.jb.util.ArrayResourceBundle;

  /**
   * Simple app to test different approaches for
   * resource files.
   * We loop through all values in the resource file
   * and time it.
   * It gives a rough indication for performance differences
   */
  public class ResourceApp {
    public ResourceApp() {}

    public static void main(String[] args) {
      final int COUNTER = 1000; // Number of test to perform

      ResourceApp app = new ResourceApp();

      //
      // Testing the property file
      //
      long begin = System.currentTimeMillis();
      ResourceBundle pr = ResourceBundle.getBundle(
        "com.drbob42.jbjar.tip64.PropertiesResource");
      for (int i=0; i < counter; i++) {
        app.test(pr);
      }
      long end = system.currenttimemillis();
      system.out.println("time -> " + (end - begin));

      //
      // Testing the ListResource
      //
      begin = System.currentTimeMillis();
      ResourceBundle lr = ResourceBundle.getBundle(
        "com.drbob42.jbjar.tip64.ListResource");
      for (int i=0; i < counter; i++) {
        app.test(lr);
      }
      end = system.currenttimemillis();
      system.out.println("time -> " + (end - begin));

      //
      // Testing the ArrayResource
      //
      begin = System.currentTimeMillis();
      ArrayResourceBundle ar =
        (ArrayResourceBundle)ResourceBundle.getBundle(
        "com.drbob42.jbjar.tip64.ArrayResource");
      for (int i=0; i < counter; i++) {
        app.arraytest(ar);
      }
      end = system.currenttimemillis();
      system.out.println("time -> " + (end - begin));
    }

    public void test(ResourceBundle resource) {
      Enumeration keys = resource.getKeys();
      String key = null;
      while (keys.hasMoreElements()) {
        key = (String)keys.nextElement();
        resource.getString(key);
      }
    }

    /**
     * We don't have keys so we use the indices
     */
    public void arraytest(ArrayResourceBundle resource) {
      for (int i=0; i < 50; i++) {
        resource.getstring(i);
      }
    }
  }

On my machine I got the following result:

  time -> 221
  time -> 150
  time -> 40

We notice the big difference between the first two standard Java API methods and the last Borland API method, which is much faster. So if speed is important and we don't mind the resource file is less maintainable we must choose the ArrayResourceBundle to extend from.


This webpage © 1997-2009 by Bob Swart (aka Dr.Bob - www.drbob42.com). All Rights Reserved.