Thoughts, Rant and Code

Curious Case of Streams in Java 8

I have been experimenting with Java 8 steams API and thinking about using it in projects I work on. Found the API to create a parallel stream from a list attractive utility for some computations.

I have been also thinking of the overhead of a parallel stream for not so large datasets.

One thing that intrigued me was the ability to get a parallel stream from a spliterator, which is available on available on all Iterable.

Did some experiments with parallel streams and noticed some real performance loss for some Iterable. The reason is, spliterator decides how fast the parallel stream can be. One of the job spliterator has to do is to decompose data into two parts, which can be processed parallel.

For example, in case of a array backed list, spliterator can determine how data can be decomposed in to two parts finely before hand. However, in case of linked list, spliterator can never be precise about the length of the data set. So it splits the data into first and rest, which is as bad as it can get.

Below is the code used for benchmarking using JMH.

The test class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class ParallelStreamSupportTest {

    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.MILLISECONDS)
    public void intStream(IntStreamProvider provider) {
        provider.getStream().mapToInt(i -> i + 2).sum();
    }

    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.MILLISECONDS)
    public void streamFromContiguousSet(ContiguousStreamProvider provider) {
        provider.getStream().mapToInt(i -> i + 2).sum();
    }

    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.MILLISECONDS)
    public void listIterator(StreamOverListProvider provider) {
        provider.getStream().mapToInt(i -> i + 2).sum();
    }

}

The provider interface.

1
2
3
4
5
6
7
public interface StreamProvider {

    final static int SIZE = 10000000;

    public Stream<Integer> getStream();

}

Provider for IntStream

1
2
3
4
5
6
7
@State(Scope.Thread)
public class IntStreamProvider implements StreamProvider {

    public Stream<Integer> getStream() {
        return IntStream.rangeClosed(1, SIZE).boxed().parallel();
    }
}

Provider for a stream from ArrayList

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@State(Scope.Thread)
public class StreamOverListProvider implements StreamProvider {

    private List<Integer> integers;

    public StreamOverListProvider() {
        Set<Integer> integer = ContiguousSet.create(Range.closed(1, SIZE), DiscreteDomain.integers());
        integers = new ArrayList<>();
        integers.addAll(integer);
    }

    public Stream<Integer> getStream() {
        return integers.parallelStream();
    }
}

Provider for a stream from a Set

1
2
3
4
5
6
7
8
9
10
11
12
13
@State(Scope.Thread)
public class ContiguousStreamProvider implements StreamProvider {

    private Set<Integer> integers;

    public ContiguousStreamProvider() {
        integers = ContiguousSet.create(Range.closed(1, SIZE), DiscreteDomain.integers());
    }

    public Stream<Integer> getStream() {
        return StreamSupport.stream(integers.spliterator(), true);
    }
}

Below is the benchmark result.

1
2
3
4
Benchmark                                                Mode  Samples   Score   Error  Units
o.s.ParallelStreamSupportTest.intStream                  avgt      200  26.438 ± 0.404  ms/op
o.s.ParallelStreamSupportTest.listIterator               avgt      200  15.549 ± 0.355  ms/op
o.s.ParallelStreamSupportTest.streamFromContiguousSet    avgt      200  56.330 ± 0.309  ms/op

From the result it quite visible that a ParallelStream over an ArrayList is the fastest one, with 15.549 ms/op. However, the benchmarking code has a flaw, where the collection behind IntStream is constructed for each iteration, where as the actual collection for other streams are pre-constructed and only stream is constructed for each iteration. But since that is not the purpose of benchmarking, I decided to ignore that, as only relative performance need to be known.

So one could consider IntStream and Stream over an ArrayList being equally fast. But stream over a Set is much slower compared to others.

Fizz Buzz in Haskell - Power of Filter and Map

Off late, I have been learning Haskell programming language. Suddenly the thought of how Fizz Buzz would look like in Haskell strike my mind.

After 5 minutes, a working version using guards and map was ready.

1
2
3
4
5
6
fizzBuzz :: Int -> [Char]
fizzBuzz n
  | mod n 15 == 0 = "FizzBuzz"
  | mod n 3  == 0 = "Fizz"
  | mod n 5 == 0 = "Buzz"
  | otherwise = show n

Then simply mapping the function to a range of first 100 was enough.

1
map fizzBuzz [1..100]

The beauty is the ability to chain multiple functions and get a working program. More or less the similar is possible in imperative languages as well. But, imagine a scenario where one need to know how many numbers are there which are divisible by both 3 and 5. Same can be obtained from the FizzBuzz function, just by chaining two more functions.

This may be a bad example of reusing function, but one gets the point. Just like the *NIX shell’s ability to chain multiple programs and get the output quickly and elegantly.

1
length (filter (=="FizzBuzz") (map fizzBuzz [1..100]))

Twitter Bootstrap and JSF

I was amazed by the magic that Twitter Bootstrap can bring into one application. If you are not a front end guy and want to develop one nice looking application, then Twitter Bootstrap is the way to go. The way it manges to arrange the layout and its basic components has always surprised me.

I decided to give a try, to use Twitter Bootstrap on a JSF implementation. Of course there was no doubt about which implementation to use. With a rich set of components Primefaces is one of my all time favorite.

The code has been hosted on Github. One can checkout here.

The screen-shot of the application can be seen here

Lessons Learned
  1. The layout classes can be very well integrated to JSF.
  2. Some of the component styling would behave weird when integrated with Primefaces.
  3. Primefaces has its own twitter-bootstrap theme. If one would like to use the default bootstrap colors and not the Layout and other basic components then this is the best option.
  4. Don’t use your own jquery version. Primefaces has one.

How to: Deploy to Weblogic Using Maven

I have always liked Maven due to its simplicity and being so powerful. One of the recent requirement needed deploying to a remote Weblogic server. Since I was using maven for dependency management and all other purposes maven is well known for, I decided to use it for remote deployment as well. Following are the steps one need to follow to make this tick.

Step 1: Getting prerequisites ready

1. A working maven installation. If you don’t have, get that here
2. Weblogic server installation with a valid domain. Get that here

Step 2: Generate Weblogic maven plugin
1
2
3
cd to Oracle Middleware installation directory
For eg: cd MW_HOME/wlserver_XX.X/server/lib/
java -jar wljarbuilder.jar -profile weblogic-maven-plugin
Step 3: Get the pom file to the weblogic lib directory
1
jar xvf MW_HOME/wlserver_XX.X/server/lib/weblogic-maven-plugin.jar META-INF/maven/com.oracle.weblogic/weblogic-maven-plugin/pom.xml

and then

1
cp MW_HOME/wlserver_XX.X/server/lib/META-INF/maven/com.oracle.weblogic/weblogic-maven-plugin/pom.xml MW_HOME/wlserver_XX.X/server/lib
Step 4: Configure the shortened command line goal

Add plugin groups to maven settings.xml (one can find this in conf directory of maven installation. It is apache-maven-3.0.4/conf/ for me) similar to below.

1
2
3
<pluginGroups>
    <pluginGroup>com.oracle.weblogic</pluginGroup>
</pluginGroups>

then edit the pom.xml in MW_HOME/wlserver_XX.X/server/lib/ similar to the below one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.oracle.weblogic</groupId>
  <artifactId>weblogic-maven-plugin</artifactId>
  <packaging>maven-plugin</packaging>
  <version>12.1.1.0</version>
  <name>Maven Mojo Archetype</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>3.0.4</version>
    </dependency>
 </dependencies>
</project>

execute the mvn install from MW_HOME/wlserver_XX.X/server/lib/ directory

1
mvn install

configure the Weblogic maven plugin to be used in local maven installation

1
mvn install:install-file -Dfile=MW_HOME/wlserver_XX.X/server/lib/weblogic-maven-plugin.jar -DpomFile=pom.xml

Now the plugin is ready to use.

Step 5: Add build goal to your pom.xml

To configure the build goal edit your project pom.xml like the below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<build>
  <plugins>
      <plugin>
          <groupId>com.oracle.weblogic</groupId>
          <artifactId>weblogic-maven-plugin</artifactId>
          <version>12.1.1.0</version>
          <configuration>
              <!-- Provide the ip address of the remote server if remote deployment-->
              <adminurl>t3://localhost:7001</adminurl>
              <user>weblogic_admin_user_id</user>
              <password>admin_password</password>
              <upload>true</upload>
              <action>deploy</action>
              <!-- Change to true if remote deployment-->
              <remote>false</remote>
              <verbose>true</verbose>
              <source>${project.build.directory}/${project.build.finalName}.${project.packaging}</source>
              <name>${project.build.finalName}</name>
          </configuration>
          <executions>
              <execution>
                  <phase>install</phase>
                  <goals>
                      <goal>deploy</goal>
                  </goals>
              </execution>
          </executions>
      </plugin>
  </plugins>
</build>

Bingo! You are done.
Start your Weblogic server and one can invoke following goal from project directory.

1
mvn clean install

Hello World

Octopress has been setup. Now its time to say hello.

1
puts "Hello World"