Monday, December 01, 2008

Is object creation is Scala really faster then Java?

The argument is that it should not be that case since Scala compiles to Java class files and runs on the same JVM/JIT, hence they are actually identical.

In my other post I claimed that for the benchmark I wrote, Scala object creation is faster. Actually, it took about 323 nano to create the java object set and only 221 nano to create the scala object set. I.e. it took about 46% more time to create the objects in Java then it would in Scala. Its pretty significant.

The code is out there so I urge you to check it out and prove me wrong.

Here is the code for creating Scala objects (from a Java Class):

public MediaContent create(){
Media media = new Media("http://javaone.com/keynote.mpg",
"Javaone Keynote", 0, 0, "video/mpg4", 1234567, 0,
123, null, Player.JAVA());
media.addPerson("Bill Gates");
media.addPerson("Steve Jobs");
Image image1 = new Image("A", "Javaone Keynote", 0, 0,
Size.LARGE());
Image image2 = new Image("B", "Javaone Keynote", 0, 0,
Size.LARGE());
MediaContent content = new MediaContent(media);
content.addImage(image1);
content.addImage(image2);
return content;
}
Here is the code that creates the matching Java object set:
public MediaContent create(){
Media media = new Media(null, "video/mpg4", Player.JAVA,
"Javaone Keynote", "http://javaone.com/keynote.mpg",
1234567, 123, 0, 0, 0);
media.addToPerson("Bill Gates");
media.addToPerson("Steve Jobs");
Image image1 = new Image(0, "Javaone Keynote", "A", 0,
Size.LARGE);
Image image2 = new Image(0, "Javaone Keynote", "B", 0,
Size.SMALL);
MediaContent content = new MediaContent(media);
content.addImage(image1);
content.addImage(image2);
return content;
}

The code as you see is almost the same. There is a minor difference with param order in the contractors, should not matter a bit, and the reference to a Scala enum Size.LARGE() which is not a real Java enum. The hidden nugget in the story is the usage of lists in Scala and Java. In Scala lists are immutable so you throw the old list once you added a new element to it. As Itay mentioned, the object immutability might makes the implementation faster.
You can also compare the Scala class set and the Java class Set and check out the benchmark runner. As expected from code I write for fun after midnight, it is fully documented for those of you who can read Java and Scala.

In Java, the way I handled lists is like this:
private List Images _images;//html generics format problem

public void addImage (Image image){
if(_images == null)
_images = new ArrayList Images();//generics format problem
_images.add(image);
}
And in Scala:var _images: List[Image] = Nil

def addImage(image: Image){
image :: _images
}

6 comments:

jau December 2, 2008 at 12:49 AM  

_imags = image :: _images

Ismael Juma December 2, 2008 at 3:19 AM  

Well, this doesn't show that object creation in Scala is faster than Java. At best it says that scala.List is faster than java.util.ArrayList for this particular benchmark. However, I haven't looked at the actual benchmark runner, so there could be many other factors at play (micro-benchmarking in the JVM is hard and it's easy to make mistakes).

Ismael

Itay Maman December 2, 2008 at 4:36 AM  

One obvious thing: In the Java code addImage() has an extra if(). How about adding an initializer to the definition of the images field?

Eishay Smith December 2, 2008 at 9:54 AM  

Thanks @jau I'll fix it and update the results.
@Ismael I agree, there is much more going on there then plain old object creation. I did worm up the JIT and tried to avoid GC, but you're right about micro benchmarking. In the Java side I counted about five object creation, not including a couple of ArrayList internal objects. The strings are interned by the JVM so I didn't count them. On that machine it takes about 7nano to create an object hence only ~60n out of 323n where spent on object creation. The rest of 260n where spent on the rest (methods, passing references etc). I'll try removing the extra if(), but I guess its insignificant. Arguably Scala actually creates more objects since each list.add() creates a new list and every primitive is an object though is probably compiled to a primitive if there is no reason to make an object out of it.

Ismael Juma December 2, 2008 at 9:57 AM  

Also note that not all objects have the same initialisation costs, so just counting the number of objects is not good enough. An ArrayList creates an internal array with 10 elements if you invoke the default constructor, for example.

The only way to compare would be to create the same classes in Java and Scala and then benchmark object creation. You will not find a difference then because the bytecode will be very similar (if not the same).

David Pollak December 3, 2008 at 3:28 PM  

There have been a number of benchmarks using Scala's immutable collections vs. the java.util.* collections. Turns out that for most real-world data sets, immutable collections work better.

Creative Commons License This work by Eishay Smith is licensed under a Creative Commons Attribution 3.0 Unported License.