The Pathfinder


Google GUICE 1000% faster than Spring !
July 5, 2007, 7:47 am
Filed under: Java

Believe it or not, Google Guice is 1000% faster than Spring. This google product wins every aspect of performance compare to Spring. From load module/context to resolve binding object, Guice is the absolute winner.I personally benchmark this two popular Dependency Injection framework myself. And I have made some scenario as if the real world application of the both framework work.

In a real world there are framework client that require objects to be injected. Typically these client performing action, receive request from actor and process the request and send the result back to the actor. These client are instance of actions in struts or webwork, or even a servlet. These action does not contains business logic, usually we put some business logic in a facade/service/manager, these facade are the instance that will injected into the client by framework.

Facade instance are managed by the framework, usually the perform logic for ex. “read user by name from access object” and do something with it. That means facade instance required dependency of Data Access Object service. Typically these service could be singleton or even prototype. It depends the architecture we built.

Data Access Objects are another instance that managed by the framework. Typically this object performing actions to access the persistent framework session, or entity manager.

In a real world, the dependency of an objects can be very complex. As your application grows, the need of an object to be able to communicate one and another or switching old object to new object are managed by the DI framework and configurable.
Based on above scenario, I made benchmark of two popular framework Google Guice and Spring.

(MainService)
          |_______ServiceOne
                                 |________ServiceFour
                                 |________ServiceFive
                                 |________ServiceSix
          |_______ServiceTwo
                                 |________ServiceSeven
                                 |________ServiceEight
                                 |________ServiceNine
          |_______ServiceThree
                                 |________ServiceTen
                                 |________ServiceEleven
                                 |________ServiceTwelve

MainService is the Facade, ServiceOne, ServiceTwo, ServiceThree are the manager, and ServiceFour until ServiceTwelve are the DAOs.
Typically as the application grows the dependency hierarchy could be more deeper and complex. But for the sake of benchmark ill keep it simple.

As I have mention before the service can be singleton or prototype. It depends on the architecture, so I will test in both fashion, in Singleton and prototype.

To give more objective on both framework, I will test the framework performance starting from one clients , and continues to 10,100,10000 client calling for request to be binded their dependency by the framework.

And also to make sure that the client is actually get the object that they want, the client will call method in service so the main service will the objects that depends on. This could be a mechanism to validate is the framework works.

The Service

public interface Service {
	public void doService();
	public Date getCreatedOn();
}

The service contains the information on when the service object is being created and method doService to perform service functionality.
All the implementation class from MainService to ServiceTwelve is implementing Service interface.

The StopWatch

public class StopWatch {
	private static final List serviceInstances = new LinkedList();

	/**
	 * @return the serviceInstances
	 */
	public List getServiceInstances() {
		return serviceInstances;
	}

	public static void recordInstance(Service service){
		serviceInstances.add(service);
	}

	public static void clear(){
		serviceInstances.clear();
	}

	public static long averageInstanceCreationInMs(){
		long total = 0;
		Date date = null;
		for (Service service : serviceInstances) {
			if(date == null){
				date = service.getCreatedOn();
			}else{
				total = total + (service.getCreatedOn().getTime() - date.getTime());
			}
		}
		return total/serviceInstances.size();
	}

	public static int totalInstance() {
		return serviceInstances.size();
	}
}

The stop watch is an object that will record the service instantiation time, and calculate the lag time between one creation of service object and another. By Counting this service creation time, and average the time, then we will find how much does the framework actually perform to binding object and inject it to the host in millisecond.

The Configuration

I separate configuration into two different files, first is the configuration for dependency that the objects are prototype and the other is singleton.

Guice Module Prototype 
public class GuiceModulePrototype extends AbstractModule{

	@Override
	protected void configure() {
		bind(Service.class).annotatedWith(Client.ClientService.class).to(MainService.class);
		bind(Service.class).annotatedWith(MainService.ServiceOne.class).to(ServiceOne.class);
		bind(Service.class).annotatedWith(MainService.ServiceTwo.class).to(ServiceTwo.class);
		bind(Service.class).annotatedWith(MainService.ServiceThree.class).to(ServiceThree.class);
		bind(Service.class).annotatedWith(ServiceOne.ServiceFour.class).to(ServiceFour.class);
		bind(Service.class).annotatedWith(ServiceOne.ServiceFive.class).to(ServiceFive.class);
		bind(Service.class).annotatedWith(ServiceOne.ServiceSix.class).to(ServiceSix.class);
		bind(Service.class).annotatedWith(ServiceTwo.ServiceSeven.class).to(ServiceSeven.class);
		bind(Service.class).annotatedWith(ServiceTwo.ServiceEight.class).to(ServiceEight.class);
		bind(Service.class).annotatedWith(ServiceTwo.ServiceNine.class).to(ServiceNine.class);
		bind(Service.class).annotatedWith(ServiceThree.ServiceTen.class).to(ServiceTen.class);
		bind(Service.class).annotatedWith(ServiceThree.ServiceEleven.class).to(ServiceEleven.class);
		bind(Service.class).annotatedWith(ServiceThree.ServiceTwelve.class).to(ServiceTwelve.class);
	}

}
Guice Module Singleton 
public class GuiceModuleSingleton extends AbstractModule{

	@Override
	protected void configure() {
	bind(Service.class).annotatedWith(Client.ClientService.class).to(MainService.class).in(Scopes.SINGLETON);
	bind(Service.class).annotatedWith(MainService.ServiceOne.class).to(ServiceOne.class).in(Scopes.SINGLETON);
        bind(Service.class).annotatedWith(MainService.ServiceTwo.class).to(ServiceTwo.class).in(Scopes.SINGLETON);
	bind(Service.class).annotatedWith(MainService.ServiceThree.class).to(ServiceThree.class).in(Scopes.SINGLETON);
        bind(Service.class).annotatedWith(ServiceOne.ServiceFour.class).to(ServiceFour.class).in(Scopes.SINGLETON);
	bind(Service.class).annotatedWith(ServiceOne.ServiceFive.class).to(ServiceFive.class).in(Scopes.SINGLETON);
        bind(Service.class).annotatedWith(ServiceOne.ServiceSix.class).to(ServiceSix.class).in(Scopes.SINGLETON);
	bind(Service.class).annotatedWith(ServiceTwo.ServiceSeven.class).to(ServiceSeven.class).in(Scopes.SINGLETON);
        bind(Service.class).annotatedWith(ServiceTwo.ServiceEight.class).to(ServiceEight.class).in(Scopes.SINGLETON);
	bind(Service.class).annotatedWith(ServiceTwo.ServiceNine.class).to(ServiceNine.class).in(Scopes.SINGLETON);
        bind(Service.class).annotatedWith(ServiceThree.ServiceTen.class).to(ServiceTen.class).in(Scopes.SINGLETON);
	....
	}
}

spring-module-singleton.xml

<beans>
<bean id="mainService" class="guice.comparison.service.MainService" >
	<property name="serviceOne">
		<ref bean="serviceOne"/>
	</property>
	<property name="serviceTwo">
		<ref bean="serviceTwo"/>
	</property>
	<property name="serviceThree">
		<ref bean="serviceThree"/>
	</property>
</bean>

<bean id="serviceOne" class="guice.comparison.service.ServiceOne" >
	<property name="serviceFour">
		<ref bean="serviceFour"/>
	</property>
.....
</beans> 
spring-module-prototype.xml

<beans>
<bean id="mainService" class="guice.comparison.service.MainService" singleton="false">
	<property name="serviceOne">
		<ref bean="serviceOne"/>
	</property>
	<property name="serviceTwo">
		<ref bean="serviceTwo"/>
	</property>
	<property name="serviceThree">
		<ref bean="serviceThree"/>
	</property>
</bean>

<bean id="serviceOne" class="guice.comparison.service.ServiceOne" singleton="false">
	<property name="serviceFour">
		<ref bean="serviceFour"/>
	</property>
....
</bean>

spring-module-client.xml

<beans>
<bean name="0" class="guice.comparison.Client" singleton="false">
<property name="service"><ref bean="mainService"/></property>
<property name="name"><value>0</value></property>
</bean>
....
....
</beans>

Above are the configuration for the spring. For Spring we still do need to create a context for clients, because in spring the client it self must be configured so the spring can inject the client dependency object.

To make it dynamic I made a simple class to create an spring xml configuration. That will automatically create xml client of n beans. “can u imagine creating xml configuration of 10000 bean by hand :( that can take days to make sure everything is in its place, Imagine you create 10000 actions that depend 13 service that means you configuration actions bloated !!”


The Main

public static void main(String[] args) throws IOException{
		boolean singleton = false;
		boolean callMethod = true;
			int client = 1;
			StopWatch.clear();
			long loadModule = springClientRequest(client,singleton,callMethod);
			System.out.println("Springt "+client+"t"+singleton+"t"+callMethod+"t"+StopWatch.averageInstanceCreationInMs()+"t"+StopWatch.totalInstance()+"t"+loadModule);

			StopWatch.clear();
			loadModule = guiceClientRequest(client,singleton,callMethod);
			System.out.println("Guicet "+client+"t"+singleton+"t"+callMethod+"t"+StopWatch.averageInstanceCreationInMs()+"t"+StopWatch.totalInstance()+"t"+loadModule);
	}

The main method will perform to create framework modules and start benchmark.

For spring framework, the client will be pulled from the spring context, as the behavior of spring where the client it self is being managed by the container.

For guice framework, the client will be instantiated and injected into the injector, and then injector bind all the object that client needs.

The result as following

#C number of client
S : Service are singleton
C : Method doPerfom is called
I : Instance created in framework
T : Average time of framework binding object into bean in ms
M : module/context startup time in ms

	#C	S	C	I	T	M
spring	1	y	y	13	34	601
guice	1	y	y	13	0	407
spring	10	y	y	13	26	607
guice	10	y	y	13	0	393
spring	100	y	y	13	28	768
guice	100	y	y	13	0	456
spring	1000	y	y	13	53	1300
guice	1000	y	y	13	0	492
spring	10000	y	y	13	35	3910
guice	10000	y	y	13	0	417 

spring	1	y	n	13	20	528
guice	1	y	n	13	0	457
spring	10	y	n	13	25	530
guice	10	y	n	13	0	392
spring	100	y	n	13	21	744
guice	100	y	n	13	0	537
spring	1000	y	n	13	34	1445
guice	1000	y	n	13	0	591
spring	10000	y	n	13	34	3819
guice	10000	y	n	13	0	401 

spring	1	n	n	13	35	660
guice	1	n	n	13	0	419
spring	10	n	n	130	88	612
guice	10	n	n	130	0	406
spring	100	n	n	1300	221	708
guice	100	n	n	1300	6	415
spring	1000	n	n	13000	877	1243
guice	1000	n	n	13000	55	386
spring	10000	n	n	130000	3858	3765
guice	10000	n	n	130000	202	400 

spring	1	n	y	13	31	567
guice	1	n	y	13	0	393
spring	10	n	y	130	67	564
guice	10	n	y	130	1	407
spring	100	n	y	1300	223	693
guice	100	n	y	1300	7	435
spring	1000	n	y	13000	957	1259
guice	1000	n	y	13000	43	424
spring	10000	n	y	130000	2931	3859
guice	10000	n	y	130000	208	405

As we can see the average time that both framework perform when injecting the bean to the client, GUICE is far more faster than Spring. In 10000 bean of client that requested to be injected of object which type is Proxy(not singleton), GUICE shows its superior where the performance is 1000% percent faster than Spring !

In Singleton service that will injected into client, GUICE has outstanding performance where almost more than 50 times faster than spring.

The results really remarkable, as we can see, the Spring load time is getting higher as the configuration getting big. In contrary Guice is relatively constant, I set Guice Stage in Production so I was expecting GUICE will perform slower, then I was wrong, GUICE does not have problems with bigger client request.

If we realize this is the benefit of GUICE architecture, GUICE does not manage all the client instance, GUICE only inject what instance that client need.

In the end, GUICE architecture has given remarkable new horizon in the new breed of ultra light weight container.

sourcecode available here



5 Reasons why I think I will not use Spring.
July 1, 2007, 5:33 am
Filed under: Java

There are several reasons why I prefer not to use SPRING.

1. Spring configuration is bloated.

My team develop enterprise application using Dependency Injection framework. There are more than 1500 classes in that project, and separated to more than 11 modules.To my experience in a real world, “we made service object less then the object who depend on that service”. If we use spring framework when we made 1000 actions who depend in 100 service, it means we have to make configuration on 1000 bean that depend on 100 service. The configuration getting worst if the actions continue growing in numbers, we must very extra carefull when we want to refactor something, we dont want to break existing code. You might start thinkin using autowire by type … no that would be a bad idea. Then … why not using autowire by name, … that sound silly what if we have different name in configuration for different object, well i guess thats gonna be another long nite at the office.

2. Putting configuration into XML is painful.

XML configuration is painful, the context painful is not something concerning how top coder you are, but more on maintenance. If you have 1000 actions then you got to be very aware what and where the configuration taken place in XML, you should have an eagle eye, you must not forget to use tools feature find and replace to change the xml configuration. Otherwise the application will blowup when going on production.

3. You loose Java Strong Type Checking if using XML configuration

When you start using XML configuration, you will loose the power of java. When you lucky the object that you inject into the bean is not what the bean wanted. You have to wait until Spring Start Running and start checking the dependency, at that time you realize you made a silly mistake. Ouchh ….

Some Configuration not using XML but in Java class, in GUICE you use module, If we want flexibility, we still can achieved by separate the business logic jar into another archive, and in the core jar we just put Class.forname(“the module class”). Thats all

4. Spring is not light weight container.

Unfortunately spring is not light weight anymore. Today Spring performance is not the fastest anymore, there are more lightweight container exist out there where the performance is better.

5. Spring is a Container that promise us to build loosely coupled application.

Spring is a container that just promise us to build loosely coupled technology, spring does not really concern that much about tightly coupled. I’m very sure that once we use spring lib other than spring-core.jar that means our application cannot live without spring.



Java User Group Indonesia 0607
July 1, 2007, 4:47 am
Filed under: Java

I was invited by Java User Group Indonesia as a speaker in regular monthly meeting held at Sun Microsystems Indonesia on June 30th 07. This time topic is GUICE. In contrary, two years ago at the same place, I speak about SPRING framework. At that time not much people are aware about spring, today the spring community in Indonesia is growing wide and here we go again, I’m standing against the main stream.

I made some example using GUICE to create web blog application using Struts 2 – Guice – JPA hibernate. To my Experience GUICE is very simple and learning curve is not as much as spring. Nothing can compare the beauty of Module and binder in GUICE, not even the Spring Java Config can do that.

The Presentation covered from simple hello world to advance GUICE such as provider, scope – “how to create custom scope” , aspect using AOP Alliance and create declarative transaction using aspect.

I made some example how we can externalize module into properties or xml, however this is not good, since we will loose the power of strong type checking in JAVA.

I recommend friends how to modularize the GUICE module, we can seperate GUICE module into different JAR, and by using Class.forname we can have the module runnin right away. We treat the module as plugins.

So …. go a head , have some GUICE.!!

Guice Presentation