26 September 2010

GWT ArrayList, HashSet and JsArray Benchmark

The performance of GWT applications varies quite a bit between the developer (hosted) mode and the compiled JavaScript code, as well as between different browsers. This blog post describes a benchmark [ Run Benchmark, Source Code ] of two different collection classes (ArrayList, HashSet) in three different environments (Chrome 6, Firefox 3.5, Dev Mode). It tests the add, contains and iterator methods, and also compares the collection classes to a lightweight JavaScript array wrapper.

The three benchmarks do basically the following:
  • The add benchmark adds 100 items to an empty collection.
  • The iterator benchmark iterates over an collection of 100 items.
  • The contains benchmark checks if 20 items are contained in a collection of 100 items. 10 of those items are contained in the collection, and another 10 are not.
Each benchmark is run 2500 times (see GWTBenchmark class).

The results I report here are rough averages from repeated measurements (~20 times) on a Core 2 Duo 2.4 GHz machine with 4GB ram, running Windows 7 64bit and GWT 2.0.3. They should be accurate with about +/- 10% error.
 Chrome
6.0.472.63 beta
Firefox
3.5.13
Dev Mode
(FF 3.5.13)
add - ArrayList19 ms550 ms14 ms
add - HashSet200 ms680 ms30 ms
add - JsArray14 ms540 ms142000 ms
iterator - ArrayList44 ms395 ms12 ms
iterator - HashSet138 ms1220 ms8 ms
contains - ArrayList4700 ms8500 ms37 ms
contains - HashSet23 ms110 ms6 ms
contains - JsArray8 ms36 ms26500 ms

Several things can be observed based on these results:

Measuring and optimizing performance in the developer mode is useless and can be dangerous. The developer mode is very different from running compiled GWT code in the browser. Code that is executed only within the Java VM tends to be a lot faster. Manipulation of the DOM and calling JavaScript using JSNI, however, is much slower (see also GWT developer guide). I was surprised by the extent of this effect, for example that Java collections are up to 125 times faster than GWT compiled code on Chrome 6 (ArrayList.contains), or that JsArray.contains is 736 times faster when compiled and run on Firefox 3.5 vs. in the developer mode on Firefox 3.5.

Chrome 6 is much faster than Firefox 3.5. This result is pretty obvious given recent browser benchmarks. However, the differences vary depending on the collection type and operation. ArrayList.contains is surprisingly slow on Chrome 6.

The different collection classes have different advantages. This is also pretty obvious given their different requirements and algorithms. The HashSet is slow for add and iterate, but fast for checking the containment of items. It also assures that each element is only contained once. The ArrayList is much faster than the HashSet when calling add and iterate, but also 200 times (Chrome 6) / 77 times (Firefox 3.6) slower when it comes to containment checks, which was surprising.

Potential speed gains when using handcrafted collection classes. The results for the JsArray class indicate that there is a potential for speed improvements by using lightweight collection classes. This finding is different from a benchmark that used bubble sort. The difference might be related to the overhead added by the GWT cross-compilation of ArrayList and HashSet.

In conclusion, when having performance issues in GWT applications that use a large number of collection instances, it might be worth looking at using optimized collection classes that reduce the overhead introduced by ArrayList and HashSet.

12 September 2010

Combining Semi-Transparent Window Borders with Opaque Content using CSS RGBa

Developing web applications that support multiple window-like panels in a single browser page is challenging. This blog post describes how I implemented semi-transparent window borders in Choosel to help with window resizing. I used CSS RGBa background colors to combine semi-transparent window borders with opaque window content.

Choosel is a GWT framework that aims at facilitating flexible visual data exploration. It supports multiple windows on the same page. The windows can be dynamically created, closed, moved, resized and brought to the front. Different window content types such as maps, charts & notes are available.

However, one of the findings from a usability study was that resizing the windows was difficult. The main reason was that the window borders were fairly thin (3 pixel). So I decided to increase the border thickness to 7 pixel. However, I found that increasing the thickness of opaque borders often occluded relevant content from underneath, e.g. from other windows. To solve this problem, I implemented semi-transparent borders using CSS. The two screenshots below illustrate the differences between the two designs:

Thin, opaque borders (click thumbnail to enlarge screenshot)


Thick, semi-transparent borders (click thumbnail to enlarge screenshot)


A window in Choosel is basically an HTML div element that contains an HTML table. The table contains cells for the borders, the header and the content. To allow for transparent boundaries and opaque window contents at the same time, I set the background color of the window div to be completely transparent using RGBa:
background-color: rgba(0, 0, 0, 0.0);
Using CSS opacity was not an option, because opacity is inherited and thus combining opaque window content with transparent border would not have been easily possible. The borders have semi-transparent background colors, again set using RGBa. The transparency of the window content depends on the implementation of the content type. For example, notes are slightly semi-transparent when inactive, but the visualization views are opaque.

The semi-transparent window borders were tested and work with Firefox 3.6, Chrome 6 and Safari 5. Choosel is not designed for Internet Explorer (up to version 8).

10 September 2010

Controlling the Z-Index of Map Overlays using the Google Maps Library for GWT

Google Maps is a great way to show location-based data on a map. In Choosel, we implemented a generic map widget which leverages Google Maps. This can for example be used to visualize the locations of recent earthquakes. Choosel also supports multiple coordinated view with selections and highlighting of items across different views (see Video):



However, occlusion in the map becomes a problem when trying to highlight resources across views. For example, when highlighting a particular earthquake in the timeline, it might be hidden by other earthquake overlays which are displayed on top of it in the map. The z-index of the earthquake overlay in the map would need to be adjusted such that the earthquake is displayed on top while being highlighted, but this is not directly possible using the Google Maps API 1.0 for GWT.

I implemented a custom Overlay class that uses a GWT label to display a data item. Using a GWT widget in the custom overlay has several advantages: (1) we can change the CSS styling, including the z-index, (2) we can use standard GWT event handlers, and (3) we don’t need to load images.

Before, we used the MapIconMaker from the gmaps utility library. The CSS based approach has some cross-browser limitation, e.g. rounded corner on IE, but it is faster because no images are loaded any more. However, the z-index changes outlined here are possible with any GWT widget, so switching to an Image widget should be easy.

This are the main elements of the LabelOverlay implementation used in Choosel:
public class LabelOverlay extends Overlay {

private Label label;

private LatLng latLng;

private MapWidget map;

private Point offset;

private MapPane pane;

private Point locationPoint;

public LabelOverlay(LatLng latLng, Point offset,
String text, String styleName) {

this.latLng = latLng;
this.offset = offset;
this.label = new Label(text);
this.label.setStyleName(styleName);
}

public HandlerRegistration addClickHandler(
ClickHandler handler) {

return label.addClickHandler(handler);
}

// ... other mouse handlers (down, move etc.)

@Override
protected final Overlay copy() {
return new LabelOverlay(latLng, offset,
label.getText(), label.getStyleName());
}

@Override
protected final void initialize(MapWidget map) {
this.map = map;

pane = map.getPane(MapPaneType.MARKER_PANE);
pane.add(label);

updatePosition(
map.convertLatLngToDivPixel(latLng));
}

@Override
protected final void redraw(boolean force) {
/*
* We check if the location has changed, because
* Google Maps allows infinite panning along the
* east-west-axis and requires an updated widget
* location in this case, although it will not
* force redrawing.
*/
Point newLocationPoint =
map.convertLatLngToDivPixel(latLng);

if (!force
&& sameLocation(newLocationPoint)) {
return;
}

updatePosition(newLocationPoint);
}

@Override
protected final void remove() {
label.removeFromParent();
}

private boolean sameLocation(Point newLocationPoint) {
assert newLocationPoint != null;
return locationPoint != null
&& locationPoint.getX()
== newLocationPoint.getX()
&& locationPoint.getY()
== newLocationPoint.getY();
}

public void setZIndex(int zIndex) {
// CSS is a class in Choosel
CSS.setZIndex(label, zIndex);
}

// ... other CSS attribute setters

private void updatePosition(Point newLocationPoint) {
assert newLocationPoint != null;
locationPoint = newLocationPoint;
pane.setWidgetPosition(label,
locationPoint.getX() + offset.getX(),
locationPoint.getY() + offset.getY());
}

}
The code uses some convenience methods from the Choosel CSS library class. The overlay are styled by default using this CSS class:
.resourceItemIcon {
width: 16px;
height: 16px;
border: 1px solid darkgray;
text-align:center;
vertical-align:middle;
font-weight:bold;
font-size: 12px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
padding: 0px;
}
The rest is pretty straightforward, the overlays are created and added:
overlay = new LabelOverlay(point, Point.newInstance(-10, -10),
label, CSS_RESOURCE_ITEM_ICON);
map.addOverlay(overlay);
In Choosel, this functionality is distributed in the MapItem and MapViewContentDisplay classes.

Using the approach outline in this blog post, you can use GWT widgets in map overlays and control CSS attributes such as the z-Index.

08 September 2010

Choosel Poster at InfoVis 2010

I will present a poster on the Choosel Framework at IEEE InfoVis 2010. The main goal of the Choosel project is to enable software developers and researchers to easily create web-based visual data exploration environments for novices. The poster paper briefly summarizes some of the related work, the features of Choosel, and the results of a prelimary usability evaluation:

Since information visualization has become increasingly vital to experts, it is now important to enable information visualization novices to consume, construct, and coordinate visualizations as well. Choosel is a web-based environment that aims at facilitating flexible visual data exploration for information visualization novices. It supports the iterative construction of multiple coordinated views during the visual data analysis process. A preliminary user study with 8 participants indicated that multiple windows, enhanced drag and drop interaction, and highlighting of items and sets, in particular, support novices in the visual data exploration process in a useful and intuitive way.

Download Poster Abstract (2 pages)

01 September 2010

Why Choosel is based on GWT

I presented Choosel to the Visual Interaction Design (VisID) research group at the University of Victoria. Choosel is an open-source framework for web-based information exploration environments aiming at information visualization novices.

The first part of my presentation focused on several design decision behind Choosel. The framework is targeting information visualization novices - those who are not familiar with information visualization and visual data analysis beyond the graphics encountered in everyday life. Two major design decision we made based on those constraints is choosing the web as the target platform and developing Choosel using GWT.

We assumed that those information visualization novices are more likely to look at smaller data sets (up to 5000 items), but are not willing to spent much time getting started with visual data analysis. This was the main driver behind the decision to develop a web-based environment, because this spares user the burden of installing software. We considered removing this entry barrier more important then scalability beyond several thousand data items. As our main goal was to a provide interactive information exploration environment, responsiveness was important and we decided to use primarily technology that runs on the user's computer and not on the server.

In Choosel, we leverage third party visualization components and toolkits such as the Simile Timeline, Protovis and FlexViz. In order to be able to integrate different technologies such as Flash and JavaScript in the browser, we decided to use a JavaScript based technologies. First, we developed a initial prototype using the dojo toolkit. However, it turned out that because of our software development skills and tool support for unit testing, refactoring, and debugging, we were able to develop the same prototype using GWT in about a quarter of the time. The current version of Choosel is based on GWT.

Here are the slides from my presentation: