Show ‘n Tell Thursday: Do you weigh in at Flyweight? (24 August 2006)


When working with a large number of (simple, similar) objects at once the amount of memory taken up by the objects can be considerable. Consider representing datapoints for a data series for a graph in objects. You might need to hold 2000 datapoints where many might be the same. Instead of wasting memory on a lot of identical objects you can use the Flyweight pattern.

In brief the pattern describes how to converve memory when working with a large number of objects by using a factory to construct objects rather than using the new keyword. By using the factory class you can do some checks before constructing a new object i.e. whether an existing object with the same properties already exists in a pool of already constructed objects. The example normally given, an the example used on Wikipedia, is that of representing a sentence where each letter is represented by an object. Using the Flyweight pattern a sentence will never use more than the 25 letter-objects (when talking ASCII) since there are no more than 25 unique letters. No need to represent each letter in the sentence as unique objects.

The sentence/letter example readily carries over to the graph example mentioned earlier.

Example

Let’s look at a simplified letter/sentence example in more detail. First the Letter class:

package com.lekkimworld.flyweight;

import java.util.HashMap;
import java.util.Map;

public class Letter {
   private static Map letters = new HashMap();
   private static int letter_count = 0;
   private char letter = 0;

   {
      // increment counter
      letter_count++;
   }

   public static Letter getInstance(char c) {
      Character c_obj = new Character(c);
      if (letters.containsKey(c_obj)) {
         // reuse existing object
         return (Letter)letters.get(c_obj);
      } else {
         // create new object
         Letter l = new Letter(c);
         letters.put(c_obj, l);
         return l;
      }
   }

   public static int getLetterCount() {
      return letter_count;
   }

   private Letter(char c) {
      this.letter = c;
   }

   public char getLetter() {
      return this.letter;
   }
}

…and then the Sentence class:

package com.lekkimworld.flyweight;

import java.util.LinkedList;
import java.util.List;

public class Sentence {
   private List letters = new LinkedList();

   public Sentence(String s) {
      for (int i=0; i<s.length(); i++) {
         letters.add(Letter.getInstance(s.charAt(i)));
      }
      System.out.println("Constructed sentence - used " + Letter.getLetterCount() +
            " instead of " + s.length() + " objects.");
   }

   public static void main(String[] args) {
      new Sentence("In the flyweight pattern, the data has no pointers " +
      	"to the data type methods, because these would consume too much space. " +
      	"Instead, the subroutines are called directly. In some cases, flyweight " +
      	"inheritance is performed by "shift-in" and "shift-out" data markers " +
      	"as a higher-level operation cycles through an array of flyweight data.");
   }

}

The output of running the example is as follows:

Constructed sentence - used 28 instead of 330 objects.

Here we saved creating 302 objects – imagine if we have been dealing with a long sentence how many object creations we could have spared the JVM and how much memory we saved. The central points are in bold in the Letter class and is the static getInstance (factory) method to create new objects, the private constructor and the Map to hold already created objects.

Conclusion

The Flyweight is a pattern that can save a lot of memory when you start representing everything as objects and the scenarios where it can be used are plentiful. I know the example is a bit simplistic but it demonstrates the point of the Flyweight pattern just fine. Don’t blame the pattern for the lack implementation in the example – blame me… 🙂

Will you weigh in at Flyweight the next time you need to handle many objects?

Further reading

While ideally suited for Java development due to the classes need to implement the pattern (static variables, a Map and normally a list of some kind) it should be possible in LotusScript – maybe using the collection classes from Johan. If you are interested the design patterns I highly suggest the Design Patterns book by GoF (Gang of Four).

This week on developerWorks!

On the This week on developerWorks! podcast for August 23rd Scott Laningham talks to Tara Hall about the release of Sametime 7.5 (shownotes). At only around 6 minutes in length the podcast is short but offer some nice information about the Sametime 7.5 SDK and links to an article on using the new SDK (Extending IBM Lotus Sametime Connect V7.5),

Be aware though! The Sametime 7.5 SDK weighs in at around 160 MB but it also contains 10 toolkits.

Changing domain names

I’m in the process of changing this blog from its old domain name at blog.lekkim.heisterberg.dk to its new domain name at lekkimworld.com so please update your bookmarks / aggregator accordingly. My Apache is currently setup to redirect the base blog URL and the RSS feed but at some point I will be removing that functionality. New URLS are as follows:

  • RSS: http://lekkimworld.com/rss.xml
  • Blog: http://lekkimworld.com

Thanks!

Suggestions for the GURUpalooza! Lotusphere session

Basically I think that with only one hour (or 90 minutes) set aside for the GURUpalooza! it would be nice and a better experience if attendees could submit the questions in advance. It was my understanding that many of the questions asked during the session…

  • should really have been asked during the week in the “ask the developers” lab (asked in the wrong forum)
  • was too specific (too many details which made the question impossible to answer without taking too much time)
  • was too unspecific (too few details which made the question impossible to answer without taking too much time)

Another point is that it seemed difficult for the “gurus” to decide who should answer the question. Posing the questions in advance would mean that questions could be assigned to the “guru” best suited for the question and questions could be (slightly) modified to make them more of less specific. The “gurus” would probably also like to combine some questions to make sure as many as possible got their question asked and answered. Answering as many questions as possible must be the main purpose of the session.

Another idea could be to hold more than one session – maybe even one per day like a returning BoF-type session. As I recall it, very few of the questions posed were actually related to any of the sessions presented during the event so having at least one more session earlier in the week wouldn’t be too much of a problem. Dividing up the “gurus” into smaller groups for a daily GURUpalooza! could also mean that more people could be “served” during the week without burdening the “gurus” too much. It would probably also take some of the pressure of that last session before the closing session.

Anyway – this is some ideas I have been playing around with. What did you think of the session?

Mark Ambler: Using LotusScript to import an image resource

I just saw that Mark Ambler wrote some code to import an image resource into a Notes database using DXL. It complements the code I wrote some time back to export an image resource from a database using DXL (Helping out a fellow blogger getting the actual bytes of an image resource – a lesson in the intricacies of DXL representation).

See the post for the complete code: Using LotusScript to import an image resource