├── .gitignore
├── LICENSE
├── README.md
├── maven -Pruntime -Druntime.iteration=10000 -Druntime.warmup=100.bat
├── maven -Pruntime.bat
├── maven -Psplit_startup -Dstartup.iteration=100 -Dstartup.warmup=10.bat
├── maven -Psplit_startup.bat
├── maven -Pstartup.bat
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── greenlaw110
│ │ └── di_benchmark
│ │ ├── DIFactory.java
│ │ ├── Main.java
│ │ ├── RuntimeBenchmark.java
│ │ ├── SplitStartupBenchmark.java
│ │ ├── StartupBenchmark.java
│ │ ├── StopWatch.java
│ │ ├── configs
│ │ ├── JBeanBoxConfig1.java
│ │ └── JBeanBoxConfig2.java
│ │ └── objects
│ │ ├── A.java
│ │ ├── A0.java
│ │ ├── B.java
│ │ ├── C.java
│ │ ├── D1.java
│ │ ├── D2.java
│ │ └── E.java
└── resources
│ └── log4j.xml
└── test
└── java
└── BenchmarkTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Mobile Tools for Java (J2ME)
4 | .mtj.tmp/
5 |
6 | # Package Files #
7 | *.jar
8 | *.war
9 | *.ear
10 |
11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
12 | hs_err_pid*
13 | .idea
14 | *.iml
15 | /target
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Green Luo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dependency Injector Benchmark Set
2 |
3 | This project benchmark the following DI solutions:
4 |
5 | * [Vanilla](https://github.com/greenlaw110/di-benchmark/blob/master/src/main/java/com/greenlaw110/di_benchmark/DIFactory.java#L24)
6 | * [Guice](https://github.com/google/guice) - 4.1.0
7 | * [Genie](https://github.com/osglworks/java-di) - 0.2.0-SNAPSHOT
8 | * [Feather](https://github.com/zsoltherpai/feather) - 1.0
9 | * [Dagger](https://github.com/square/dagger) - 1.2.5
10 | * [Pico](http://picocontainer.com/) - 2.15
11 | * [jBeanBox](https://github.com/drinkjava2/jBeanBox) - 2.4.1
12 | * [Spring](http://projects.spring.io/spring-framework/) - 4.3.2.RELEASE
13 |
14 | ## Object Graph
15 |
16 | Below is the object graph of the class to be injected in the benchmark program
17 |
18 | ```
19 | Object
20 | └── A
21 | └── B
22 | └── C
23 | ├── D1
24 | └── D2
25 | └── E
26 | ```
27 |
28 | All injection is done through Constructor injection
29 |
30 | ## Benchmarks
31 |
32 | ### Startup and first time fetch benchmark
33 |
34 | ```
35 | Split Starting up DI containers & instantiating a dependency graph 4999 times:
36 | -------------------------------------------------------------------------------
37 | Vanilla| start: 3ms fetch: 5ms
38 | Guice| start: 458ms fetch: 800ms
39 | Feather| start: 8ms fetch: 73ms
40 | Dagger| start: 46ms fetch: 130ms
41 | Pico| start: 166ms fetch: 161ms
42 | Genie| start: 478ms fetch: 98ms
43 | jBeanBoxNormal| start: 7ms fetch: 339ms
44 | jBeanBoxTypeSafe| start: 3ms fetch: 162ms
45 | jBeanBoxAnnotation| start: 4ms fetch: 597ms
46 | SpringJavaConfiguration| start: 13956ms fetch: 1149ms
47 | SpringAnnotationScanned| start: 22302ms fetch: 2738ms
48 | ```
49 |
50 | ### Runtime bean injection benchmark
51 |
52 | ```
53 | Runtime benchmark, fetch new bean for 50K times:
54 | ---------------------------------------------------------
55 | Vanilla| 3ms
56 | Guice| 188ms
57 | Feather| 68ms
58 | Dagger| 28ms
59 | Genie| 45ms
60 | Pico| 353ms
61 | jBeanBoxNormal| 1698ms
62 | jBeanBoxTypeSafe| 880ms
63 | jBeanBoxAnnotation| 2591ms
64 | SpringJavaConfiguration| 1936ms
65 | SpringAnnotationScanned| 2369ms
66 | ```
67 |
68 | ```
69 | Runtime benchmark, fetch new bean for 5M times:
70 | ---------------------------------------------------------
71 | Vanilla| 242ms
72 | Guice| 3022ms
73 | Feather| 1748ms
74 | Dagger| 842ms
75 | Genie| 1043ms
76 | Pico| 13185ms
77 | jBeanBoxNormal| Timeout
78 | jBeanBoxTypeSafe| 74607ms
79 | jBeanBoxAnnotation| Timeout
80 | SpringJavaConfiguration| Timeout
81 | SpringAnnotationScanned| Timeout
82 | ```
83 |
84 | ```
85 | Runtime benchmark, fetch singleton bean for 5M times:
86 | ---------------------------------------------------------
87 | Vanilla| 5ms
88 | Guice| 559ms
89 | Feather| 180ms
90 | Dagger| 746ms
91 | Genie| 118ms
92 | Pico| 225ms
93 | jBeanBoxNormal| 59ms
94 | jBeanBoxTypeSafe| 59ms
95 | jBeanBoxAnnotation| 105ms
96 | SpringJavaConfiguration| 245ms
97 | SpringAnnotationScanned| 228ms
98 | ```
99 |
100 | ## How to run the benchmark
101 |
102 | You need JDK8 and [maven](http://maven.apache.org/) to run the benchmark program.
103 |
104 | The project defined two profiles: `runtime` and `split_startup`.
105 |
106 | ```bash
107 | #Run the `runtime` profile:
108 | mvn clean compile exec:exec -Pruntime
109 | ```
110 |
111 | This will run the Runtime benchmark, which fetch the bean of class `A` (as shown above) for `50K` times
112 |
113 | ```bash
114 | #To run the `split_startup` profile:
115 | mvn clean compile exec:exec -Psplit_startup
116 | ```
117 |
118 | This will run the startup benchmark, which initialize the injector and load bean of class `A` for `5K` times.
119 |
120 | To tune the warm up and iterations:
121 |
122 | ```
123 | #For startup benchmark:
124 | mvn clean compile exec:exec -Psplit_startup -Dstartup.iteration=100 -Dstartup.warmup=10
125 | ```
126 |
127 | ```
128 | #For runtime benchmark:
129 | mvn clean compile exec:exec -Pruntime -Druntime.iteration=1000 -Druntime.warmup=100
130 | ```
131 |
132 | To benchmark singleton injection:
133 |
134 | ```
135 | mvn clean compile exec:exec -Pruntime -Dsingleton=true
136 | ```
137 |
138 | ## Disclaim
139 |
140 | The benchmark source code is originated from https://github.com/zsoltherpai/feather/tree/master/performance-test and adapted by [Gelin Luo](https://github.com/greenlaw110)
141 |
--------------------------------------------------------------------------------
/maven -Pruntime -Druntime.iteration=10000 -Druntime.warmup=100.bat:
--------------------------------------------------------------------------------
1 | @echo This test need JDK8+
2 | call mvn clean compile exec:exec -Pruntime -Druntime.iteration=10000 -Druntime.warmup=100
3 | @pause
--------------------------------------------------------------------------------
/maven -Pruntime.bat:
--------------------------------------------------------------------------------
1 | @echo This test need JDK8+
2 | call mvn clean compile exec:exec -Pruntime
3 | @pause
--------------------------------------------------------------------------------
/maven -Psplit_startup -Dstartup.iteration=100 -Dstartup.warmup=10.bat:
--------------------------------------------------------------------------------
1 | @echo This test need JDK8+
2 | call mvn clean compile exec:exec -Psplit_startup -Dstartup.iteration=100 -Dstartup.warmup=10
3 | @pause
--------------------------------------------------------------------------------
/maven -Psplit_startup.bat:
--------------------------------------------------------------------------------
1 | @echo This test need JDK8+
2 | call mvn clean compile exec:exec -Psplit_startup
3 | @pause
--------------------------------------------------------------------------------
/maven -Pstartup.bat:
--------------------------------------------------------------------------------
1 | @echo This test need JDK8+
2 | call mvn clean compile exec:exec -Pstartup
3 | @pause
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | org.osgl
5 | di-benchmark
6 | jar
7 | 1.0-SNAPSHOT
8 | di-benchmark
9 | http://maven.apache.org
10 |
11 | org.sonatype.oss
12 | oss-parent
13 | 7
14 |
15 |
16 | UTF-8
17 | UTF-8
18 | 1.8
19 | runtime
20 | 1000
21 | false
22 | 49999
23 | 200
24 | 4999
25 |
26 |
27 |
28 | junit
29 | junit
30 | 4.12
31 | test
32 |
33 |
34 | org.osgl
35 | osgl-tool
36 | 0.9.0-SNAPSHOT
37 |
38 |
39 | org.codejargon.feather
40 | feather
41 | 1.0
42 |
43 |
44 | com.google.inject
45 | guice
46 | 4.1.0
47 |
48 |
49 | org.picocontainer
50 | picocontainer
51 | 2.15
52 |
53 |
54 | com.squareup.dagger
55 | dagger
56 | 1.2.5
57 |
58 |
59 | com.squareup.dagger
60 | dagger-compiler
61 | 1.2.5
62 | true
63 |
64 |
65 | org.springframework
66 | spring-context
67 | 4.3.2.RELEASE
68 |
69 |
70 | org.osgl
71 | genie
72 | 0.2.0-SNAPSHOT
73 |
74 |
75 | log4j
76 | log4j
77 | 1.2.17
78 | runtime
79 |
80 |
81 | com.github.drinkjava2
82 | jbeanbox
83 | 2.4.1
84 |
85 |
86 |
87 |
88 |
89 |
90 | org.apache.maven.plugins
91 | maven-compiler-plugin
92 | 3.3
93 |
94 | ${java.version}
95 | ${java.version}
96 |
97 |
98 |
99 |
100 |
101 |
102 | runtime
103 |
104 |
105 |
106 | org.codehaus.mojo
107 | exec-maven-plugin
108 | 1.5.0
109 |
110 |
111 |
112 | exec
113 |
114 |
115 |
116 |
117 | java
118 |
119 | -Xms512m
120 | -Xmx512m
121 | -classpath
122 |
123 | -Dsingleton=${singleton}
124 | -Dwarmup=${runtime.warmup}
125 | -Diteration=${runtime.iteration}
126 | -Dtype=runtime
127 | com.greenlaw110.di_benchmark.Main
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 | startup
136 |
137 |
138 |
139 | org.codehaus.mojo
140 | exec-maven-plugin
141 | 1.5.0
142 |
143 |
144 |
145 | exec
146 |
147 |
148 |
149 |
150 | java
151 |
152 | -server
153 | -Xms512m
154 | -Xmx512m
155 | -classpath
156 |
157 | -Dwarmup=${startup.warmup}
158 | -Diteration=${startup.iteration}
159 | -Dtype=startup
160 | com.greenlaw110.di_benchmark.Main
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | split_startup
169 |
170 |
171 |
172 | org.codehaus.mojo
173 | exec-maven-plugin
174 | 1.5.0
175 |
176 |
177 |
178 | exec
179 |
180 |
181 |
182 |
183 | java
184 |
185 | -Xms512m
186 | -Xmx512m
187 | -classpath
188 |
189 | -Dwarmup=${startup.warmup}
190 | -Diteration=${startup.iteration}
191 | -Dtype=split_startup
192 | com.greenlaw110.di_benchmark.Main
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/DIFactory.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark;
2 |
3 | import com.greenlaw110.di_benchmark.objects.*;
4 | import org.codejargon.feather.Feather;
5 | import org.osgl.inject.Genie;
6 | import org.osgl.inject.ScopeCache;
7 | import org.picocontainer.DefaultPicoContainer;
8 | import org.picocontainer.MutablePicoContainer;
9 | import org.springframework.context.ApplicationContext;
10 | import org.springframework.context.annotation.AnnotationConfigApplicationContext;
11 | import org.springframework.context.annotation.Bean;
12 | import org.springframework.context.annotation.Configuration;
13 | import org.springframework.context.annotation.Scope;
14 |
15 | import com.github.drinkjava2.BeanBoxContext;
16 | import com.google.inject.Guice;
17 | import com.google.inject.Injector;
18 | import com.greenlaw110.di_benchmark.configs.JBeanBoxConfig1;
19 | import com.greenlaw110.di_benchmark.configs.JBeanBoxConfig2;
20 |
21 | import dagger.Module;
22 | import dagger.ObjectGraph;
23 |
24 | import javax.inject.Provider;
25 | import java.util.HashMap;
26 | import java.util.Map;
27 |
28 | public class DIFactory {
29 |
30 | public static class VanillaContainer {
31 |
32 | private static final A0 A0 = getA0();
33 |
34 | @SuppressWarnings("unchecked")
35 | public T getInstance(Class instanceClass) {
36 | if (A.class.equals(instanceClass)) {
37 | return (T) getA();
38 | } else if (A0.getClass().equals(instanceClass)) {
39 | return (T) A0;
40 | }
41 | return null;
42 | }
43 |
44 | private static A getA() {
45 | E e = new E();
46 | D1 d1 = new D1(e);
47 | D2 d2 = new D2(e);
48 | C c = new C(d1, d2);
49 | B b = new B(c);
50 | return new A(b);
51 | }
52 |
53 | private static A0 getA0() {
54 | E e = new E();
55 | D1 d1 = new D1(e);
56 | D2 d2 = new D2(e);
57 | C c = new C(d1, d2);
58 | B b = new B(c);
59 | return new A0(b);
60 | }
61 | }
62 |
63 | public static VanillaContainer vanilla() {
64 | return new VanillaContainer();
65 | }
66 |
67 | public static Injector guice() {
68 | return Guice.createInjector();
69 | }
70 |
71 | public static Feather feather() {
72 | return Feather.with();
73 | }
74 |
75 | public static MutablePicoContainer pico() {
76 | MutablePicoContainer pico = new DefaultPicoContainer();
77 | pico.addComponent(A.class);
78 | pico.addComponent(B.class);
79 | pico.addComponent(C.class);
80 | pico.addComponent(D1.class);
81 | pico.addComponent(D2.class);
82 | pico.addComponent(E.class);
83 | return pico;
84 | }
85 |
86 | public static Genie genie() {
87 | final Map singletonRepo = new HashMap<>();
88 | Genie genie = Genie.createWithoutPlugins();
89 | genie.registerProvider(ScopeCache.SingletonScope.class, new Provider() {
90 | @Override
91 | public ScopeCache.SingletonScope get() {
92 | return new ScopeCache.SingletonScope() {
93 | @Override
94 | public T get(Class aClass) {
95 | return (T) singletonRepo.get(aClass);
96 | }
97 |
98 | @Override
99 | public void put(Class aClass, T t) {
100 | singletonRepo.put(aClass, t);
101 | }
102 | };
103 | }
104 | });
105 | return genie;
106 | }
107 |
108 | public static ObjectGraph dagger() {
109 | return ObjectGraph.create(new DaggerModule());
110 | }
111 |
112 | @Module(injects = {A.class, A0.class})
113 | public static class DaggerModule {
114 | @dagger.Provides
115 | E e() {
116 | return new E();
117 | }
118 | }
119 |
120 | public static BeanBoxContext jbeanboxNormal() {
121 | return new BeanBoxContext(JBeanBoxConfig1.class).setIgnoreAnnotation(true);
122 | }
123 |
124 | public static BeanBoxContext jbeanboxTypeSafe() {
125 | return new BeanBoxContext(JBeanBoxConfig2.class).setIgnoreAnnotation(true);
126 | }
127 |
128 | public static BeanBoxContext jbeanboxAnnotation() {
129 | return new BeanBoxContext();
130 | }
131 |
132 | public static ApplicationContext spring(boolean scan) {
133 | if (scan) {
134 | return new AnnotationConfigApplicationContext("com.greenlaw110.di_benchmark.objects");
135 | } else {
136 | return new AnnotationConfigApplicationContext(SpringConfig.class);
137 | }
138 | }
139 |
140 | @Configuration
141 | static class SpringConfig {
142 | @Bean
143 | @Scope("prototype")
144 | public A a() {
145 | return new A(b());
146 | }
147 |
148 | @Bean
149 | public A0 a0() {
150 | return new A0(b());
151 | }
152 |
153 | @Bean
154 | @Scope("prototype")
155 | public B b() {
156 | return new B(c());
157 | }
158 |
159 | @Bean
160 | @Scope("prototype")
161 | public C c() {
162 | return new C(d1(), d2());
163 | }
164 |
165 | @Bean
166 | @Scope("prototype")
167 | public D1 d1() {
168 | return new D1(e());
169 | }
170 |
171 | @Bean
172 | @Scope("prototype")
173 | public D2 d2() {
174 | return new D2(e());
175 | }
176 |
177 | @Bean
178 | @Scope("prototype")
179 | public E e() {
180 | return new E();
181 | }
182 |
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/Main.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark;
2 |
3 | import org.osgl.util.S;
4 |
5 | public class Main {
6 |
7 | private static final int WARM_UP = 200;
8 | private static final int ITERATION = 20000;
9 |
10 | public static void main(String[] args) {
11 | int warmUp = WARM_UP;
12 | int iteration = ITERATION;
13 | String singletonStr = conf("singleton");
14 | boolean singleton = S.notBlank(singletonStr) && Boolean.parseBoolean(singletonStr);
15 | String s = conf("warmup");
16 | if (S.notBlank(s)) {
17 | warmUp = Integer.parseInt(s);
18 | }
19 | s = conf("iteration");
20 | if (S.notBlank(s)) {
21 | iteration = Integer.parseInt(s);
22 | }
23 | s = conf("type");
24 | if (S.eq(s, "runtime")) {
25 | new RuntimeBenchmark().run(warmUp, iteration, singleton);
26 | }
27 | if (S.eq(s, "startup")) {
28 | new StartupBenchmark().run(warmUp, iteration);
29 | }
30 | if (S.eq(s, "split_startup")) {
31 | new SplitStartupBenchmark().run(iteration);
32 | }
33 | }
34 |
35 | private static String conf(String key) {
36 | return System.getProperty(key);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/RuntimeBenchmark.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark;
2 |
3 | import static com.greenlaw110.di_benchmark.DIFactory.dagger;
4 | import static com.greenlaw110.di_benchmark.DIFactory.genie;
5 | import static com.greenlaw110.di_benchmark.DIFactory.guice;
6 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxAnnotation;
7 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxNormal;
8 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxTypeSafe;
9 | import static com.greenlaw110.di_benchmark.DIFactory.pico;
10 | import static com.greenlaw110.di_benchmark.DIFactory.spring;
11 | import static com.greenlaw110.di_benchmark.DIFactory.vanilla;
12 |
13 | import com.greenlaw110.di_benchmark.objects.A0;
14 | import org.codejargon.feather.Feather;
15 | import org.osgl.inject.Genie;
16 | import org.picocontainer.MutablePicoContainer;
17 | import org.springframework.context.ApplicationContext;
18 |
19 | import com.github.drinkjava2.BeanBoxContext;
20 | import com.google.inject.Injector;
21 | import com.greenlaw110.di_benchmark.DIFactory.VanillaContainer;
22 | import com.greenlaw110.di_benchmark.objects.A;
23 |
24 | import dagger.ObjectGraph;
25 |
26 | /**
27 | * Measures bootstrap cost of different DI tools. An iteration includes creating
28 | * an injector and instantiating the dependency graph.
29 | */
30 | public class RuntimeBenchmark {
31 |
32 | private static Class A_CLS = A.class;
33 | private static Class A_SINGLETON_CLS = A0.class;
34 |
35 | public void run(final int warmup, final int iterations, final boolean singleton) {
36 | benchmarkExplanation(iterations, singleton);
37 | VanillaContainer vanilla = vanilla();
38 | Injector guice = guice();
39 | Feather feather = Feather.with();
40 | ObjectGraph dagger = dagger();
41 | MutablePicoContainer pico = pico();
42 | Genie genie = genie();
43 | BeanBoxContext jbeanboxNormal = jbeanboxNormal();
44 | BeanBoxContext jbeanboxTypeSafe = jbeanboxTypeSafe();
45 | BeanBoxContext jbeanboxAnnotation = jbeanboxAnnotation();
46 | ApplicationContext spring = spring(false);
47 | ApplicationContext springScan = spring(true);
48 |
49 | final Class> CLS = singleton ? A_SINGLETON_CLS : A_CLS;
50 |
51 | for (int i = 0; i < warmup; ++i) {
52 | feather.instance(CLS);
53 | genie.get(CLS);
54 | guice.getInstance(CLS);
55 | pico.getComponent(CLS);
56 | dagger.get(CLS);
57 | spring.getBean(CLS);
58 | if (!singleton) {
59 | jbeanboxNormal.getBean(CLS);
60 | jbeanboxTypeSafe.getBean(CLS);
61 | jbeanboxAnnotation.getBean(CLS);
62 | }
63 | }
64 |
65 | StopWatch.millis("Vanilla", () -> {
66 | for (int i = 0; i < iterations; ++i) {
67 | vanilla.getInstance(CLS);
68 | }
69 | });
70 |
71 | StopWatch.millis("Guice", () -> {
72 | for (int i = 0; i < iterations; ++i) {
73 | guice.getInstance(CLS);
74 | }
75 | });
76 |
77 | StopWatch.millis("Feather", () -> {
78 | for (int i = 0; i < iterations; ++i) {
79 | feather.instance(CLS);
80 | }
81 | });
82 |
83 | StopWatch.millis("Dagger", () -> {
84 | for (int i = 0; i < iterations; ++i) {
85 | dagger.get(CLS);
86 | }
87 | });
88 |
89 | StopWatch.millis("Genie", () -> {
90 | for (int i = 0; i < iterations; ++i) {
91 | genie.get(CLS);
92 | }
93 | });
94 |
95 | StopWatch.millis("Pico", () -> {
96 | for (int i = 0; i < iterations; ++i) {
97 | pico.getComponent(CLS);
98 | }
99 | });
100 |
101 | //if (!singleton) {
102 | if (singleton || iterations < 500000) {
103 | StopWatch.millis("jBeanBoxNormal", () -> {
104 | for (int i = 0; i < iterations; ++i) {
105 | jbeanboxNormal.getBean(CLS);
106 | }
107 | });
108 | }
109 | StopWatch.millis("jBeanBoxTypeSafe", () -> {
110 | for (int i = 0; i < iterations; ++i) {
111 | jbeanboxTypeSafe.getBean(CLS);
112 | }
113 | });
114 | if (singleton || iterations < 500000) {
115 | StopWatch.millis("jBeanBoxAnnotation", () -> {
116 | for (int i = 0; i < iterations; ++i) {
117 | jbeanboxAnnotation.getBean(CLS);
118 | }
119 | });
120 | }
121 | //}
122 |
123 | if (singleton || iterations < 500000) {
124 | StopWatch.millis("SpringJavaConfiguration", () -> {
125 | for (int i = 0; i < iterations; ++i) {
126 | spring.getBean(CLS);
127 | }
128 | });
129 | }
130 | if (singleton || iterations < 500000) {
131 | StopWatch.millis("SpringAnnotationScanned", () -> {
132 | for (int i = 0; i < iterations; ++i) {
133 | springScan.getBean(CLS);
134 | }
135 | });
136 | }
137 |
138 | }
139 |
140 | private void benchmarkExplanation(int iterations, boolean singleton) {
141 | System.out.println(String.format("Runtime benchmark, fetch %s bean for %s times:\n%s",
142 | singleton ? "singleton" : "new", iterations,
143 | "---------------------------------------------------------"));
144 | }
145 |
146 | }
147 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/SplitStartupBenchmark.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark;
2 |
3 | import static com.greenlaw110.di_benchmark.DIFactory.dagger;
4 | import static com.greenlaw110.di_benchmark.DIFactory.genie;
5 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxAnnotation;
6 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxNormal;
7 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxTypeSafe;
8 | import static com.greenlaw110.di_benchmark.DIFactory.pico;
9 | import static com.greenlaw110.di_benchmark.DIFactory.spring;
10 |
11 | import org.codejargon.feather.Feather;
12 | import org.osgl.inject.Genie;
13 | import org.picocontainer.MutablePicoContainer;
14 | import org.springframework.context.ApplicationContext;
15 |
16 | import com.github.drinkjava2.BeanBoxContext;
17 | import com.google.inject.Guice;
18 | import com.google.inject.Injector;
19 | import com.greenlaw110.di_benchmark.DIFactory.VanillaContainer;
20 | import com.greenlaw110.di_benchmark.objects.A;
21 |
22 | import dagger.ObjectGraph;
23 |
24 | /**
25 | * Measures bootstrap cost of different DI tools. An iteration includes creating
26 | * an injector and instantiating the dependency graph.
27 | */
28 | public class SplitStartupBenchmark {
29 |
30 | public void run(final int iterations) {
31 | benchmarkExplanation(iterations);
32 |
33 | StopWatch.startAndFetch("Vanilla", (start, fetch) -> {
34 | for (int i = 0; i < iterations; ++i) {
35 | long ms = System.currentTimeMillis();
36 | VanillaContainer injector = new VanillaContainer();
37 | long ms2 = System.currentTimeMillis();
38 | start.addAndGet(ms2 - ms);
39 | injector.getInstance(A.class);
40 | fetch.addAndGet(System.currentTimeMillis() - ms2);
41 | }
42 | });
43 | StopWatch.startAndFetch("Guice", (start, fetch) -> {
44 | for (int i = 0; i < iterations; ++i) {
45 | long ms = System.currentTimeMillis();
46 | Injector injector = Guice.createInjector();
47 | long ms2 = System.currentTimeMillis();
48 | start.addAndGet(ms2 - ms);
49 | injector.getInstance(A.class);
50 | fetch.addAndGet(System.currentTimeMillis() - ms2);
51 | }
52 | });
53 | StopWatch.startAndFetch("Feather", (start, fetch) -> {
54 | for (int i = 0; i < iterations; ++i) {
55 | long ms = System.currentTimeMillis();
56 | Feather feather = Feather.with();
57 | long ms2 = System.currentTimeMillis();
58 | start.addAndGet(ms2 - ms);
59 | feather.instance(A.class);
60 | fetch.addAndGet(System.currentTimeMillis() - ms2);
61 | }
62 | });
63 | StopWatch.startAndFetch("Dagger", (start, fetch) -> {
64 | for (int i = 0; i < iterations; ++i) {
65 | long ms = System.currentTimeMillis();
66 | ObjectGraph dagger = dagger();
67 | long ms2 = System.currentTimeMillis();
68 | start.addAndGet(ms2 - ms);
69 | dagger.get(A.class);
70 | fetch.addAndGet(System.currentTimeMillis() - ms2);
71 | }
72 | });
73 | StopWatch.startAndFetch("Pico", (start, fetch) -> {
74 | for (int i = 0; i < iterations; ++i) {
75 | long ms = System.currentTimeMillis();
76 | MutablePicoContainer pico = pico();
77 | long ms2 = System.currentTimeMillis();
78 | start.addAndGet(ms2 - ms);
79 | pico.getComponent(A.class);
80 | fetch.addAndGet(System.currentTimeMillis() - ms2);
81 | }
82 | });
83 | StopWatch.startAndFetch("Genie", (start, fetch) -> {
84 | for (int i = 0; i < iterations; ++i) {
85 | long ms = System.currentTimeMillis();
86 | Genie genie = genie();
87 | long ms2 = System.currentTimeMillis();
88 | start.addAndGet(ms2 - ms);
89 | genie.get(A.class);
90 | fetch.addAndGet(System.currentTimeMillis() - ms2);
91 | }
92 | });
93 | StopWatch.startAndFetch("jBeanBoxNormal", (start, fetch) -> {
94 | for (int i = 0; i < iterations; ++i) {
95 | long ms = System.currentTimeMillis();
96 | BeanBoxContext jbeanboxNormal = jbeanboxNormal();
97 | long ms2 = System.currentTimeMillis();
98 | start.addAndGet(ms2 - ms);
99 | jbeanboxNormal.getBean(A.class);
100 | fetch.addAndGet(System.currentTimeMillis() - ms2);
101 | }
102 | });
103 | StopWatch.startAndFetch("jBeanBoxTypeSafe", (start, fetch) -> {
104 | for (int i = 0; i < iterations; ++i) {
105 | long ms = System.currentTimeMillis();
106 | BeanBoxContext jbeanboxTypeSafe = jbeanboxTypeSafe();
107 | long ms2 = System.currentTimeMillis();
108 | start.addAndGet(ms2 - ms);
109 | jbeanboxTypeSafe.getBean(A.class);
110 | fetch.addAndGet(System.currentTimeMillis() - ms2);
111 | }
112 | });
113 | StopWatch.startAndFetch("jBeanBoxAnnotation", (start, fetch) -> {
114 | for (int i = 0; i < iterations; ++i) {
115 | long ms = System.currentTimeMillis();
116 | BeanBoxContext jbeanboxAnnotation = jbeanboxAnnotation();
117 | long ms2 = System.currentTimeMillis();
118 | start.addAndGet(ms2 - ms);
119 | jbeanboxAnnotation.getBean(A.class);
120 | fetch.addAndGet(System.currentTimeMillis() - ms2);
121 | }
122 | });
123 |
124 | if (iterations < 500000) {
125 | StopWatch.startAndFetch("SpringJavaConfiguration", (start, fetch) -> {
126 | for (int i = 0; i < iterations; ++i) {
127 | long ms = System.currentTimeMillis();
128 | ApplicationContext applicationContext = spring(false);
129 | long ms2 = System.currentTimeMillis();
130 | start.addAndGet(ms2 - ms);
131 | applicationContext.getBean(A.class);
132 | fetch.addAndGet(System.currentTimeMillis() - ms2);
133 | }
134 | });
135 | }
136 | if (iterations < 500000) {
137 | StopWatch.startAndFetch("SpringAnnotationScanned", (start, fetch) -> {
138 | for (int i = 0; i < iterations; ++i) {
139 | long ms = System.currentTimeMillis();
140 | ApplicationContext applicationContext = spring(true);
141 | long ms2 = System.currentTimeMillis();
142 | start.addAndGet(ms2 - ms);
143 | applicationContext.getBean(A.class);
144 | fetch.addAndGet(System.currentTimeMillis() - ms2);
145 | }
146 | });
147 | }
148 |
149 | }
150 |
151 | private void benchmarkExplanation(int iterations) {
152 | System.out.println(
153 | String.format("Split Starting up DI containers & instantiating a dependency graph %s times:\n%s",
154 | iterations, "-------------------------------------------------------------------------------"));
155 | }
156 |
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/StartupBenchmark.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark;
2 |
3 | import static com.greenlaw110.di_benchmark.DIFactory.dagger;
4 | import static com.greenlaw110.di_benchmark.DIFactory.genie;
5 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxAnnotation;
6 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxNormal;
7 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxTypeSafe;
8 | import static com.greenlaw110.di_benchmark.DIFactory.pico;
9 | import static com.greenlaw110.di_benchmark.DIFactory.spring;
10 | import static com.greenlaw110.di_benchmark.DIFactory.vanilla;
11 |
12 | import org.codejargon.feather.Feather;
13 | import org.osgl.inject.Genie;
14 | import org.picocontainer.MutablePicoContainer;
15 | import org.springframework.context.ApplicationContext;
16 |
17 | import com.github.drinkjava2.BeanBoxContext;
18 | import com.google.inject.Guice;
19 | import com.google.inject.Injector;
20 | import com.greenlaw110.di_benchmark.DIFactory.VanillaContainer;
21 | import com.greenlaw110.di_benchmark.objects.A;
22 |
23 | import dagger.ObjectGraph;
24 |
25 | /**
26 | * Measures bootstrap cost of different DI tools. An iteration includes creating
27 | * an injector and instantiating the dependency graph.
28 | */
29 | public class StartupBenchmark {
30 |
31 | public void run(final int warmup, final int iterations) {
32 | benchmarkExplanation(iterations);
33 | for (int i = 0; i < warmup; ++i) {
34 | vanilla().getInstance(A.class);
35 | Feather.with().instance(A.class);
36 | genie().get(A.class);
37 | Guice.createInjector().getInstance(A.class);
38 | pico().getComponent(A.class);
39 | dagger().get(A.class);
40 | jbeanboxNormal().getBean(A.class);
41 | jbeanboxTypeSafe().getBean(A.class);
42 | jbeanboxAnnotation().getBean(A.class);
43 | spring(false).getBean(A.class);
44 | spring(true).getBean(A.class);
45 | }
46 | StopWatch.millis("Vanilla", () -> {
47 | for (int i = 0; i < iterations; ++i) {
48 | VanillaContainer vanilla = new VanillaContainer();
49 | vanilla.getInstance(A.class);
50 | }
51 | });
52 | StopWatch.millis("Guice", () -> {
53 | for (int i = 0; i < iterations; ++i) {
54 | Injector injector = Guice.createInjector();
55 | injector.getInstance(A.class);
56 | }
57 | });
58 | StopWatch.millis("Feather", () -> {
59 | for (int i = 0; i < iterations; ++i) {
60 | Feather feather = Feather.with();
61 | feather.instance(A.class);
62 | }
63 | });
64 | StopWatch.millis("Dagger", () -> {
65 | for (int i = 0; i < iterations; ++i) {
66 | ObjectGraph dagger = dagger();
67 | dagger.get(A.class);
68 | }
69 | });
70 | StopWatch.millis("Pico", () -> {
71 | for (int i = 0; i < iterations; ++i) {
72 | MutablePicoContainer pico = pico();
73 | pico.getComponent(A.class);
74 | }
75 | });
76 | StopWatch.millis("Genie", () -> {
77 | for (int i = 0; i < iterations; ++i) {
78 | Genie genie = genie();
79 | genie.get(A.class);
80 | }
81 | });
82 | StopWatch.millis("jBeanBoxAnnotation", () -> {
83 | for (int i = 0; i < iterations; ++i) {
84 | BeanBoxContext jbeanboxAnnotation = jbeanboxAnnotation();
85 | jbeanboxAnnotation.getBean(A.class);
86 | }
87 | });
88 | StopWatch.millis("jBeanBoxTypeSafe", () -> {
89 | for (int i = 0; i < iterations; ++i) {
90 | BeanBoxContext jbeanboxTypeSafe = jbeanboxTypeSafe();
91 | jbeanboxTypeSafe.getBean(A.class);
92 | }
93 | });
94 | StopWatch.millis("jBeanBoxNormal", () -> {
95 | for (int i = 0; i < iterations; ++i) {
96 | BeanBoxContext jbeanboxNormal = jbeanboxNormal();
97 | jbeanboxNormal.getBean(A.class);
98 | }
99 | });
100 | if (iterations < 500000) {
101 | StopWatch.millis("SpringJavaConfiguration", () -> {
102 | for (int i = 0; i < iterations; ++i) {
103 | ApplicationContext applicationContext = spring(false);
104 | applicationContext.getBean(A.class);
105 | }
106 | });
107 | }
108 | if (iterations < 500000) {
109 | StopWatch.millis("SpringAnnotationScanned", () -> {
110 | for (int i = 0; i < iterations; ++i) {
111 | ApplicationContext applicationContext = spring(true);
112 | applicationContext.getBean(A.class);
113 | }
114 | });
115 | }
116 | }
117 |
118 | private void benchmarkExplanation(int iterations) {
119 | System.out.println(String.format("Starting up DI containers & instantiating a dependency graph %s times:\n%s",
120 | iterations, "------------------------------------------------------------------------"));
121 | }
122 |
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/StopWatch.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark;
2 |
3 | import java.util.concurrent.atomic.AtomicLong;
4 |
5 | public class StopWatch {
6 |
7 | public static void millis(String description, Runnable runnable) {
8 | long start = System.currentTimeMillis();
9 | runnable.run();
10 | long end = System.currentTimeMillis();
11 | System.out.println(String.format("%28s|%6sms", description, end - start));
12 | }
13 |
14 | interface StartAndFetch {
15 | void run(AtomicLong startup, AtomicLong fetch);
16 | }
17 |
18 | public static void startAndFetch(String description, StartAndFetch runnable) {
19 | AtomicLong startup = new AtomicLong(0);
20 | AtomicLong fetch = new AtomicLong(0);
21 | runnable.run(startup, fetch);
22 | System.out.println(String.format("%28s| start:%6sms fetch:%6sms", description, startup.get(), fetch.get()));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/configs/JBeanBoxConfig1.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark.configs;
2 |
3 | import com.github.drinkjava2.BeanBox;
4 | import com.github.drinkjava2.BeanBoxContext;
5 | import com.greenlaw110.di_benchmark.objects.A;
6 | import com.greenlaw110.di_benchmark.objects.A0;
7 | import com.greenlaw110.di_benchmark.objects.B;
8 | import com.greenlaw110.di_benchmark.objects.C;
9 | import com.greenlaw110.di_benchmark.objects.D1;
10 | import com.greenlaw110.di_benchmark.objects.D2;
11 | import com.greenlaw110.di_benchmark.objects.E;
12 |
13 | public class JBeanBoxConfig1 {
14 | public static class ProtoTypeBox extends BeanBox {
15 | {this.setPrototype(true);}
16 | }
17 |
18 | public static class ABox extends ProtoTypeBox {
19 | {
20 | this.setConstructor(A.class, B.class);
21 | }
22 | }
23 |
24 | public static class A0Box extends BeanBox {
25 | {
26 | this.setConstructor(A0.class, B.class);
27 | }
28 | }
29 |
30 | public static class BBox extends ProtoTypeBox {
31 | {
32 | this.setConstructor(B.class, C.class);
33 | }
34 | }
35 |
36 | public static class CBox extends ProtoTypeBox {
37 | {
38 | this.setConstructor(C.class, D1.class, D2.class);
39 | }
40 | }
41 |
42 | public static class D1Box extends ProtoTypeBox {
43 | {
44 | this.setConstructor(D1.class, E.class);
45 | }
46 | }
47 |
48 | public static class D2Box extends ProtoTypeBox {
49 | {
50 | this.setConstructor(D2.class, E.class);
51 | }
52 | }
53 |
54 | public static class EBox extends ProtoTypeBox {
55 | {
56 | this.setClassOrValue(E.class);
57 | }
58 | }
59 |
60 | public static void main(String[] args) {
61 | BeanBoxContext ctx = new BeanBoxContext(JBeanBoxConfig1.class).setIgnoreAnnotation(true);
62 | ctx.getBean(A.class);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/configs/JBeanBoxConfig2.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark.configs;
2 |
3 | import com.github.drinkjava2.BeanBox;
4 | import com.github.drinkjava2.BeanBoxContext;
5 | import com.greenlaw110.di_benchmark.objects.A;
6 | import com.greenlaw110.di_benchmark.objects.A0;
7 | import com.greenlaw110.di_benchmark.objects.B;
8 | import com.greenlaw110.di_benchmark.objects.C;
9 | import com.greenlaw110.di_benchmark.objects.D1;
10 | import com.greenlaw110.di_benchmark.objects.D2;
11 | import com.greenlaw110.di_benchmark.objects.E;
12 |
13 | public class JBeanBoxConfig2 {
14 |
15 | public static class ProtoTypeBox extends BeanBox {
16 | {this.setPrototype(true);}
17 | }
18 |
19 | public static class ABox extends ProtoTypeBox {
20 | public A create() {
21 | return new A(context.getBean(B.class));
22 | }
23 | }
24 |
25 | public static class A0Box extends BeanBox {
26 | public A0 create() {
27 | return new A0(context.getBean(B.class));
28 | }
29 | }
30 |
31 | public static class BBox extends ProtoTypeBox {
32 | public B create() {
33 | return new B(context.getBean(C.class));
34 | }
35 | }
36 |
37 | public static class CBox extends ProtoTypeBox {
38 | public C create() {
39 | return new C(context.getBean(D1.class), context.getBean(D2.class));
40 | }
41 | }
42 |
43 | public static class D1Box extends ProtoTypeBox {
44 | public D1 create() {
45 | return new D1(context.getBean(E.class));
46 | }
47 | }
48 |
49 | public static class D2Box extends ProtoTypeBox {
50 | public D2 create() {
51 | return new D2(context.getBean(E.class));
52 | }
53 | }
54 |
55 | public static class EBox extends ProtoTypeBox {
56 | public E create() {
57 | return new E();
58 | }
59 | }
60 |
61 | public static void main(String[] args) {
62 | BeanBoxContext ctx = new BeanBoxContext(JBeanBoxConfig2.class).setIgnoreAnnotation(true);
63 | ctx.getBean(A.class);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/objects/A.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark.objects;
2 |
3 | import java.util.Objects;
4 |
5 | import javax.inject.Inject;
6 |
7 | import org.springframework.context.annotation.Scope;
8 | import org.springframework.stereotype.Component;
9 |
10 | import com.github.drinkjava2.InjectBox;
11 |
12 | @InjectBox(prototype = true) // for jBeanBox usage
13 | @Component // for Spring usage
14 | @Scope("prototype") // for Spring usage
15 | public class A {
16 | private final B b;
17 |
18 | @InjectBox // for jBeanBox
19 | @Inject // for JSR330 compliant DI libraries
20 | public A(B b) {
21 | this.b = b;
22 | }
23 |
24 | @Override
25 | public boolean equals(Object o) {
26 | if (this == o)
27 | return true;
28 | if (o == null || getClass() != o.getClass())
29 | return false;
30 | A a = (A) o;
31 | return Objects.equals(b, a.b);
32 | }
33 |
34 | @Override
35 | public int hashCode() {
36 | return Objects.hash(b);
37 | }
38 |
39 | @Override
40 | public String toString() {
41 | return getClass().getSimpleName();
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/objects/A0.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark.objects;
2 |
3 | import com.github.drinkjava2.InjectBox;
4 | import org.springframework.context.annotation.Scope;
5 | import org.springframework.stereotype.Component;
6 |
7 | import javax.inject.Inject;
8 | import javax.inject.Singleton;
9 | import java.util.Objects;
10 |
11 | @Component // for Spring usage
12 | @Singleton // for JSR330 compliant DI library usage
13 | public class A0 {
14 | private final B b;
15 |
16 | @InjectBox // for jBeanBox
17 | @Inject // for JSR330 compliant DI libraries
18 | public A0(B b) {
19 | this.b = b;
20 | }
21 |
22 | @Override
23 | public boolean equals(Object o) {
24 | if (this == o)
25 | return true;
26 | if (o == null || getClass() != o.getClass())
27 | return false;
28 | A0 a = (A0) o;
29 | return Objects.equals(b, a.b);
30 | }
31 |
32 | @Override
33 | public int hashCode() {
34 | return Objects.hash(b);
35 | }
36 |
37 | @Override
38 | public String toString() {
39 | return getClass().getSimpleName();
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/objects/B.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark.objects;
2 |
3 | import java.util.Objects;
4 |
5 | import javax.inject.Inject;
6 |
7 | import org.springframework.context.annotation.Scope;
8 | import org.springframework.stereotype.Component;
9 |
10 | import com.github.drinkjava2.InjectBox;
11 |
12 | @InjectBox(prototype = true) // for jBeanBox usage
13 | @Component // for Spring usage
14 | @Scope("prototype") // for Spring usage
15 | public class B {
16 | private final C c;
17 |
18 | @InjectBox // for jBeanBox
19 | @Inject // for JSR330 compliant DI libraries
20 | public B(C c) {
21 | this.c = c;
22 | }
23 |
24 | @Override
25 | public boolean equals(Object o) {
26 | if (this == o)
27 | return true;
28 | if (o == null || getClass() != o.getClass())
29 | return false;
30 | B b = (B) o;
31 | return Objects.equals(c, b.c);
32 | }
33 |
34 | @Override
35 | public int hashCode() {
36 | return Objects.hash(c);
37 | }
38 |
39 | @Override
40 | public String toString() {
41 | return getClass().getSimpleName();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/objects/C.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark.objects;
2 |
3 | import org.springframework.context.annotation.Scope;
4 | import org.springframework.stereotype.Component;
5 |
6 | import com.github.drinkjava2.InjectBox;
7 |
8 | import javax.inject.Inject;
9 | import java.util.Objects;
10 |
11 | @InjectBox(prototype = true) // for jBeanBox usage
12 | @Component // for Spring usage
13 | @Scope("prototype") // for Spring usage
14 | public class C {
15 | private final D1 d1;
16 | private final D2 d2;
17 |
18 | @InjectBox // for jBeanBox
19 | @Inject // for JSR330 compliant DI libraries
20 | public C(D1 d1, D2 d2) {
21 | this.d1 = d1;
22 | this.d2 = d2;
23 | }
24 |
25 | @Override
26 | public boolean equals(Object o) {
27 | if (this == o)
28 | return true;
29 | if (o == null || getClass() != o.getClass())
30 | return false;
31 | C c = (C) o;
32 | return Objects.equals(d1, c.d1) && Objects.equals(d2, c.d2);
33 | }
34 |
35 | @Override
36 | public int hashCode() {
37 | return Objects.hash(d1, d2);
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return getClass().getSimpleName();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/objects/D1.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark.objects;
2 |
3 | import org.springframework.context.annotation.Scope;
4 | import org.springframework.stereotype.Component;
5 |
6 | import com.github.drinkjava2.BeanBox;
7 | import com.github.drinkjava2.InjectBox;
8 |
9 | import javax.inject.Inject;
10 | import java.util.Objects;
11 |
12 | @InjectBox(prototype = true) // for jBeanBox usage
13 | @Component // for Spring usage
14 | @Scope("prototype") // for Spring usage
15 | public class D1 {
16 |
17 | @InjectBox // for jBeanBox
18 | @Inject // for JSR330 compliant DI libraries
19 | public D1(E e) {
20 | }
21 |
22 | @Override
23 | public int hashCode() {
24 | return Objects.hash("d1");
25 | }
26 |
27 | @Override
28 | public boolean equals(Object obj) {
29 | if (obj == this) {
30 | return true;
31 | }
32 | return (obj instanceof D1);
33 | }
34 |
35 | @Override
36 | public String toString() {
37 | return getClass().getSimpleName();
38 | }
39 |
40 | public static void main(String[] args) {
41 | BeanBox.getBean(D1.class);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/objects/D2.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark.objects;
2 |
3 | import java.util.Objects;
4 |
5 | import javax.inject.Inject;
6 |
7 | import org.springframework.context.annotation.Scope;
8 | import org.springframework.stereotype.Component;
9 |
10 | import com.github.drinkjava2.BeanBox;
11 | import com.github.drinkjava2.InjectBox;
12 |
13 | @InjectBox(prototype = true) // for jBeanBox usage
14 | @Component // for Spring usage
15 | @Scope("prototype") // for Spring usage
16 | public class D2 {
17 | private final E e;
18 |
19 | @InjectBox // for jBeanBox
20 | @Inject // for JSR330 compliant DI libraries
21 | public D2(E e) {
22 | this.e = e;
23 | }
24 |
25 | @Override
26 | public boolean equals(Object o) {
27 | if (this == o)
28 | return true;
29 | if (o == null || getClass() != o.getClass())
30 | return false;
31 | D2 d2 = (D2) o;
32 | return Objects.equals(e, d2.e);
33 | }
34 |
35 | @Override
36 | public int hashCode() {
37 | return Objects.hash(e);
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return getClass().getSimpleName();
43 | }
44 |
45 | public static void main(String[] args) {
46 | BeanBox.getBean(A.class);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/greenlaw110/di_benchmark/objects/E.java:
--------------------------------------------------------------------------------
1 | package com.greenlaw110.di_benchmark.objects;
2 |
3 | import java.util.Objects;
4 |
5 | import org.springframework.context.annotation.Scope;
6 | import org.springframework.stereotype.Component;
7 |
8 | import com.github.drinkjava2.InjectBox;
9 |
10 | @InjectBox(prototype = true) // for jBeanBox usage
11 | @Component // for Spring usage
12 | @Scope("prototype") // for Spring usage
13 | public class E {
14 |
15 | @Override
16 | public int hashCode() {
17 | return Objects.hashCode("e");
18 | }
19 |
20 | @Override
21 | public boolean equals(Object obj) {
22 | if (obj == this) {
23 | return true;
24 | }
25 | return (obj instanceof E);
26 | }
27 |
28 | @Override
29 | public String toString() {
30 | return getClass().getSimpleName();
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/resources/log4j.xml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/src/test/java/BenchmarkTest.java:
--------------------------------------------------------------------------------
1 | import static com.greenlaw110.di_benchmark.DIFactory.dagger;
2 | import static com.greenlaw110.di_benchmark.DIFactory.feather;
3 | import static com.greenlaw110.di_benchmark.DIFactory.genie;
4 | import static com.greenlaw110.di_benchmark.DIFactory.guice;
5 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxAnnotation;
6 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxNormal;
7 | import static com.greenlaw110.di_benchmark.DIFactory.jbeanboxTypeSafe;
8 | import static com.greenlaw110.di_benchmark.DIFactory.pico;
9 | import static com.greenlaw110.di_benchmark.DIFactory.spring;
10 | import static com.greenlaw110.di_benchmark.DIFactory.vanilla;
11 |
12 | import org.codejargon.feather.Feather;
13 | import org.junit.Assert;
14 | import org.junit.BeforeClass;
15 | import org.osgl.inject.Genie;
16 | import org.picocontainer.PicoContainer;
17 | import org.springframework.context.ApplicationContext;
18 |
19 | import com.github.drinkjava2.BeanBoxContext;
20 | import com.google.inject.Injector;
21 | import com.greenlaw110.di_benchmark.DIFactory.VanillaContainer;
22 | import com.greenlaw110.di_benchmark.objects.A;
23 |
24 | import dagger.ObjectGraph;
25 |
26 | public class BenchmarkTest extends Assert {
27 |
28 | static VanillaContainer vanilla;
29 | static Injector guice;
30 | static Feather feather;
31 | static ObjectGraph dagger;
32 | static PicoContainer pico;
33 | static Genie genie;
34 | static ApplicationContext spring;
35 | static BeanBoxContext jbeanboxNormal;
36 | static BeanBoxContext jbeanboxTypeSafe;
37 | static BeanBoxContext jbeanboxAnnotation;
38 |
39 | @BeforeClass
40 | public static void setup() {
41 | vanilla = vanilla();
42 | guice = guice();
43 | feather = feather();
44 | dagger = dagger();
45 | pico = pico();
46 | genie = genie();
47 | spring = spring(true);
48 | jbeanboxNormal = jbeanboxNormal();
49 | jbeanboxTypeSafe = jbeanboxTypeSafe();
50 | jbeanboxAnnotation = jbeanboxAnnotation();
51 | }
52 |
53 | @org.junit.Test
54 | public void equality() {
55 | A vanillaA = vanilla.getInstance(A.class);
56 | A guiceA = guice.getInstance(A.class);
57 | A featherA = feather.instance(A.class);
58 | A daggerA = dagger.get(A.class);
59 | A picoA = pico.getComponent(A.class);
60 | A genieA = genie.get(A.class);
61 | A springA = spring.getBean(A.class);
62 | A jbeanboxNormalA = jbeanboxNormal.getBean(A.class);
63 | A jbeanboxTypeSafeA = jbeanboxTypeSafe.getBean(A.class);
64 | A jbeanboxAnnotatioA = jbeanboxAnnotation.getBean(A.class);
65 |
66 | eq(vanillaA, guiceA);
67 | eq(guiceA, featherA);
68 | eq(featherA, daggerA);
69 | eq(daggerA, picoA);
70 | eq(picoA, genieA);
71 | eq(genieA, springA);
72 | eq(springA, jbeanboxNormalA);
73 | eq(jbeanboxNormalA, jbeanboxTypeSafeA);
74 | eq(jbeanboxTypeSafeA, jbeanboxAnnotatioA);
75 | }
76 |
77 | @org.junit.Test
78 | public void identity() {
79 | A vanillaA = vanilla.getInstance(A.class);
80 | A guiceA = guice.getInstance(A.class);
81 | A featherA = feather.instance(A.class);
82 | A daggerA = dagger.get(A.class);
83 | A picoA = pico.getComponent(A.class);
84 | A genieA = genie.get(A.class);
85 | A springA = spring.getBean(A.class);
86 | A jbeanboxNormalA = jbeanboxNormal.getBean(A.class);
87 | A jbeanboxTypeSafeA = jbeanboxTypeSafe.getBean(A.class);
88 | A jbeanboxAnnotatioA = jbeanboxAnnotation.getBean(A.class);
89 |
90 | A vanillaB = vanilla.getInstance(A.class);
91 | A guiceB = guice.getInstance(A.class);
92 | A featherB = feather.instance(A.class);
93 | A daggerB = dagger.get(A.class);
94 | A picoB = pico.getComponent(A.class);
95 | A genieB = genie.get(A.class);
96 | A springB = spring.getBean(A.class);
97 | A jbeanboxNormalB = jbeanboxNormal.getBean(A.class);
98 | A jbeanboxTypeSafeB = jbeanboxTypeSafe.getBean(A.class);
99 | A jbeanboxAnnotatioB = jbeanboxAnnotation.getBean(A.class);
100 |
101 | assertNotSame(vanillaA, vanillaB);
102 | assertNotSame(guiceA, guiceB);
103 | assertNotSame(featherA, featherB);
104 | assertNotSame(daggerA, daggerB);
105 | assertNotSame(picoA, picoB);
106 | assertNotSame(genieA, genieB);
107 | assertNotSame(springA, springB);
108 | assertNotSame(jbeanboxNormalA, jbeanboxNormalB);
109 | assertNotSame(jbeanboxTypeSafeA, jbeanboxTypeSafeB);
110 | assertNotSame(jbeanboxAnnotatioA, jbeanboxAnnotatioB);
111 | }
112 |
113 | private void eq(Object a, Object b) {
114 | assertEquals(a, b);
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------