1   /*
2    * BeanMappingPerfTest - Tests Java Bean to Java Bean mapping
3    * Copyright (C) 2007 Christian Schenk
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    * 
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18   */
19  package org.christianschenk.beanmapping;
20  
21  import java.lang.reflect.InvocationTargetException;
22  import java.util.ArrayList;
23  import java.util.List;
24  
25  import net.sf.dozer.util.mapping.DozerBeanMapper;
26  import net.sf.dozer.util.mapping.MapperIF;
27  
28  import org.apache.commons.beanutils.BeanUtils;
29  import org.apache.log4j.Logger;
30  import org.christianschenk.beanintrospect.BeanIntrospector;
31  import org.christianschenk.beanmapping.beans.IntBean;
32  import org.junit.Test;
33  
34  import static org.junit.Assert.assertEquals;
35  
36  public class PerformanceComparison {
37  
38  	private static final Logger log = Logger.getLogger(PerformanceComparison.class);
39  	// it's just fair to initialize these classes only once
40  	private static final BeanIntrospector beanIntrospector = new BeanIntrospector();
41  	private static final MapperIF dozer = new DozerBeanMapper();
42  
43  	private enum Command {
44  		HAND, INTROSPECTOR, COMMONS, SPRING, DOZER;
45  	}
46  
47  	@Test
48  	public void test() {
49  		final List<Runnable> runners = new ArrayList<Runnable>();
50  		this.fillRunners(runners, 1);
51  		final int[] counts = { 10, 100, 1000, 10000, 20000, 50000, 100000 };
52  		this.runPerformanceTest(runners, counts);
53  
54  		for (final int numberOfCreatedBeans : counts) {
55  			this.fillRunners(runners, numberOfCreatedBeans);
56  			this.runPerformanceTest(runners, new int[] { 1 });
57  		}
58  	}
59  
60  	private void fillRunners(final List<Runnable> runners, final int nrOfBeans) {
61  		runners.clear();
62  		for (final Command command : Command.values()) {
63  			runners.add(this.getRunnable(command, nrOfBeans));
64  		}
65  	}
66  
67  	private void runPerformanceTest(final List<Runnable> runners, final int[] counts) {
68  		log.debug("Runs\tByHand\tIntrospector\tCommons\tSpring\tDozer");
69  		for (final int count : counts) {
70  			final long times[] = new long[runners.size()];
71  			int i = 0;
72  			for (final Runnable runner : runners) {
73  				long time = System.nanoTime();
74  				for (int runs = 0; runs < count; runs++) {
75  					runner.run();
76  				}
77  				time = System.nanoTime() - time;
78  				times[i++] = time / (1000 * 1000);
79  			}
80  			log.debug(count + "\t" + times[0] + "\t" + times[1] + "\t\t" + times[2] + "\t" + times[3] + "\t" + times[4]);
81  		}
82  	}
83  
84  	private Runnable getRunnable(final Command command, final int nrOfBeans) {
85  		return new Runnable() {
86  			public void run() {
87  				final IntBean intBean1 = new IntBean(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
88  				for (int i = 0; i < nrOfBeans; i++) {
89  					final IntBean intBean2 = new IntBean();
90  					doCommand(command, intBean1, intBean2);
91  					assertIntBeans(intBean1, intBean2);
92  				}
93  			}
94  		};
95  	}
96  
97  	private void doCommand(final Command command, final IntBean intBean1, final IntBean intBean2) {
98  		switch (command) {
99  		case HAND:
100 			intBean2.setInt1(intBean1.getInt1());
101 			intBean2.setInt2(intBean1.getInt2());
102 			intBean2.setInt3(intBean1.getInt3());
103 			intBean2.setInt4(intBean1.getInt4());
104 			intBean2.setInt5(intBean1.getInt5());
105 			intBean2.setInt6(intBean1.getInt6());
106 			intBean2.setInt7(intBean1.getInt7());
107 			intBean2.setInt8(intBean1.getInt8());
108 			intBean2.setInt9(intBean1.getInt9());
109 			intBean2.setInt10(intBean1.getInt10());
110 			break;
111 		case INTROSPECTOR:
112 			beanIntrospector.fill(intBean2, intBean1);
113 			break;
114 		case COMMONS:
115 			try {
116 				BeanUtils.copyProperties(intBean2, intBean1);
117 			} catch (IllegalAccessException ex) {
118 				throw new RuntimeException(ex);
119 			} catch (InvocationTargetException ex) {
120 				throw new RuntimeException(ex);
121 			}
122 			break;
123 		case SPRING:
124 			org.springframework.beans.BeanUtils.copyProperties(intBean1, intBean2);
125 			break;
126 		case DOZER:
127 			dozer.map(intBean1, intBean2);
128 			break;
129 		}
130 	}
131 
132 	private static final void assertIntBeans(final IntBean intBean1, final IntBean intBean2) {
133 		if (true) return;
134 		assertEquals(1, intBean1.getInt1());
135 		assertEquals(1, intBean2.getInt1());
136 		assertEquals(2, intBean1.getInt2());
137 		assertEquals(2, intBean2.getInt2());
138 		assertEquals(3, intBean1.getInt3());
139 		assertEquals(3, intBean2.getInt3());
140 		assertEquals(4, intBean1.getInt4());
141 		assertEquals(4, intBean2.getInt4());
142 		assertEquals(5, intBean1.getInt5());
143 		assertEquals(5, intBean2.getInt5());
144 		assertEquals(6, intBean1.getInt6());
145 		assertEquals(6, intBean2.getInt6());
146 		assertEquals(7, intBean1.getInt7());
147 		assertEquals(7, intBean2.getInt7());
148 		assertEquals(8, intBean1.getInt8());
149 		assertEquals(8, intBean2.getInt8());
150 		assertEquals(9, intBean1.getInt9());
151 		assertEquals(9, intBean2.getInt9());
152 		assertEquals(10, intBean1.getInt10());
153 		assertEquals(10, intBean2.getInt10());
154 	}
155 }