Merge "Fix xml->CompositeNode transformation for rpc replies for rpcs with no output"
[yangtools.git] / benchmarks / src / main / java / org / opendaylight / yangtools / yang / data / impl / tree / InMemoryDataTreeBenchmark.java
1 /**
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.impl.tree;
9
10 import java.io.IOException;
11 import java.util.concurrent.TimeUnit;
12 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
13 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
14 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
15 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
16 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
17 import org.opendaylight.yangtools.yang.data.api.schema.tree.*;
18 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
19 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
20 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
21 import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
22 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
23 import org.openjdk.jmh.annotations.*;
24 import org.openjdk.jmh.runner.Runner;
25 import org.openjdk.jmh.runner.RunnerException;
26 import org.openjdk.jmh.runner.options.Options;
27 import org.openjdk.jmh.runner.options.OptionsBuilder;
28
29 /**
30  * Benchmarking of InMemoryDataTree performance.
31  *
32  * JMH is used for microbenchmarking.
33  *
34  * @author Lukas Sedlak <lsedlak@cisco.com>
35  *
36  * @see <a href="http://openjdk.java.net/projects/code-tools/jmh/">JMH</a>
37  */
38 @State(Scope.Thread)
39 @BenchmarkMode(Mode.AverageTime)
40 @OutputTimeUnit(TimeUnit.MILLISECONDS)
41 public class InMemoryDataTreeBenchmark {
42
43     private static final int OUTER_LIST_100K = 100000;
44     private static final int OUTER_LIST_50K = 50000;
45     private static final int OUTER_LIST_10K = 10000;
46
47     private static final YangInstanceIdentifier[] OUTER_LIST_100K_PATHS = initOuterListPaths(OUTER_LIST_100K);
48     private static final YangInstanceIdentifier[] OUTER_LIST_50K_PATHS = initOuterListPaths(OUTER_LIST_50K);
49     private static final YangInstanceIdentifier[] OUTER_LIST_10K_PATHS = initOuterListPaths(OUTER_LIST_10K);
50
51     private static YangInstanceIdentifier[] initOuterListPaths(final int outerListPathsCount) {
52         final YangInstanceIdentifier[] paths = new YangInstanceIdentifier[outerListPathsCount];
53
54         for (int outerListKey = 0; outerListKey < outerListPathsCount; ++outerListKey) {
55             paths[outerListKey] = YangInstanceIdentifier.builder(BenchmarkModel.OUTER_LIST_PATH)
56                 .nodeWithKey(BenchmarkModel.OUTER_LIST_QNAME, BenchmarkModel.ID_QNAME, outerListKey)
57                 .build();
58         }
59         return paths;
60     }
61
62     private static final MapNode ONE_ITEM_INNER_LIST = initInnerListItems(1);
63     private static final MapNode TWO_ITEM_INNER_LIST = initInnerListItems(2);
64     private static final MapNode TEN_ITEM_INNER_LIST = initInnerListItems(10);
65
66     private static MapNode initInnerListItems(final int count) {
67         final CollectionNodeBuilder<MapEntryNode, MapNode> mapEntryBuilder = ImmutableNodes
68             .mapNodeBuilder(BenchmarkModel.INNER_LIST_QNAME);
69
70         for (int i = 1; i <= count; ++i) {
71             mapEntryBuilder
72                 .withChild(ImmutableNodes.mapEntry(BenchmarkModel.INNER_LIST_QNAME, BenchmarkModel.NAME_QNAME, i));
73         }
74
75         return mapEntryBuilder.build();
76     }
77
78     private static final NormalizedNode<?, ?>[] OUTER_LIST_ONE_ITEM_INNER_LIST = initOuterListItems(OUTER_LIST_100K, ONE_ITEM_INNER_LIST);
79     private static final NormalizedNode<?, ?>[] OUTER_LIST_TWO_ITEM_INNER_LIST = initOuterListItems(OUTER_LIST_50K, TWO_ITEM_INNER_LIST);
80     private static final NormalizedNode<?, ?>[] OUTER_LIST_TEN_ITEM_INNER_LIST = initOuterListItems(OUTER_LIST_10K, TEN_ITEM_INNER_LIST);
81
82     private static NormalizedNode<?,?>[] initOuterListItems(int outerListItemsCount, MapNode innerList) {
83         final NormalizedNode<?,?>[] outerListItems = new NormalizedNode[outerListItemsCount];
84
85         for (int i = 0; i < outerListItemsCount; ++i) {
86             int outerListKey = i;
87             outerListItems[i] = ImmutableNodes.mapEntryBuilder(BenchmarkModel.OUTER_LIST_QNAME, BenchmarkModel.ID_QNAME, outerListKey)
88                 .withChild(innerList).build();
89         }
90         return outerListItems;
91     }
92
93     private SchemaContext schemaContext;
94     private DataTree datastore;
95
96     public static void main(String... args) throws IOException, RunnerException {
97         Options opt = new OptionsBuilder()
98             .include(".*" + InMemoryDataTreeBenchmark.class.getSimpleName() + ".*")
99             .forks(1)
100             .build();
101
102         new Runner(opt).run();
103     }
104
105     @Setup(Level.Trial)
106     public void setup() throws DataValidationFailedException {
107         schemaContext = BenchmarkModel.createTestContext();
108         final InMemoryDataTreeFactory factory = InMemoryDataTreeFactory.getInstance();
109         datastore = factory.create();
110         datastore.setSchemaContext(schemaContext);
111         final DataTreeSnapshot snapshot = datastore.takeSnapshot();
112         initTestNode(snapshot);
113     }
114
115     @TearDown
116     public void tearDown() {
117         schemaContext = null;
118         datastore = null;
119     }
120
121     private void initTestNode(final DataTreeSnapshot snapshot) throws DataValidationFailedException {
122         final DataTreeModification modification = snapshot.newModification();
123         final YangInstanceIdentifier testPath = YangInstanceIdentifier.builder(BenchmarkModel.TEST_PATH)
124             .build();
125
126         modification.write(testPath, provideOuterListNode());
127         datastore.validate(modification);
128         final DataTreeCandidate candidate = datastore.prepare(modification);
129         datastore.commit(candidate);
130     }
131
132     private DataContainerChild<?, ?> provideOuterListNode() {
133         return ImmutableContainerNodeBuilder
134             .create()
135             .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(BenchmarkModel.TEST_QNAME))
136             .withChild(
137                 ImmutableNodes.mapNodeBuilder(BenchmarkModel.OUTER_LIST_QNAME)
138                     .build()).build();
139     }
140
141     @Benchmark
142     @Warmup(iterations = 10, timeUnit = TimeUnit.MILLISECONDS)
143     @Measurement(iterations = 20, timeUnit = TimeUnit.MILLISECONDS)
144     public void write100KSingleNodeWithOneInnerItemInOneCommitBenchmark() throws Exception {
145         final DataTreeSnapshot snapshot = datastore.takeSnapshot();
146         final DataTreeModification modification = snapshot.newModification();
147         for (int outerListKey = 0; outerListKey < OUTER_LIST_100K; ++outerListKey) {
148             modification.write(OUTER_LIST_100K_PATHS[outerListKey], OUTER_LIST_ONE_ITEM_INNER_LIST[outerListKey]);
149         }
150         datastore.validate(modification);
151         final DataTreeCandidate candidate = datastore.prepare(modification);
152         datastore.commit(candidate);
153     }
154
155     @Benchmark
156     @Warmup(iterations = 10, timeUnit = TimeUnit.MILLISECONDS)
157     @Measurement(iterations = 20, timeUnit = TimeUnit.MILLISECONDS)
158     public void write100KSingleNodeWithOneInnerItemInCommitPerWriteBenchmark() throws Exception {
159         final DataTreeSnapshot snapshot = datastore.takeSnapshot();
160         for (int outerListKey = 0; outerListKey < OUTER_LIST_100K; ++outerListKey) {
161             final DataTreeModification modification = snapshot.newModification();
162             modification.write(OUTER_LIST_100K_PATHS[outerListKey], OUTER_LIST_ONE_ITEM_INNER_LIST[outerListKey]);
163             datastore.validate(modification);
164             final DataTreeCandidate candidate = datastore.prepare(modification);
165             datastore.commit(candidate);
166         }
167     }
168
169     @Benchmark
170     @Warmup(iterations = 10, timeUnit = TimeUnit.MILLISECONDS)
171     @Measurement(iterations = 20, timeUnit = TimeUnit.MILLISECONDS)
172     public void write50KSingleNodeWithTwoInnerItemsInOneCommitBenchmark() throws Exception {
173         final DataTreeSnapshot snapshot = datastore.takeSnapshot();
174         final DataTreeModification modification = snapshot.newModification();
175         for (int outerListKey = 0; outerListKey < OUTER_LIST_50K; ++outerListKey) {
176             modification.write(OUTER_LIST_50K_PATHS[outerListKey], OUTER_LIST_TWO_ITEM_INNER_LIST[outerListKey]);
177         }
178         datastore.validate(modification);
179         final DataTreeCandidate candidate = datastore.prepare(modification);
180         datastore.commit(candidate);
181     }
182
183     @Benchmark
184     @Warmup(iterations = 10, timeUnit = TimeUnit.MILLISECONDS)
185     @Measurement(iterations = 20, timeUnit = TimeUnit.MILLISECONDS)
186     public void write50KSingleNodeWithTwoInnerItemsInCommitPerWriteBenchmark() throws Exception {
187         final DataTreeSnapshot snapshot = datastore.takeSnapshot();
188         for (int outerListKey = 0; outerListKey < OUTER_LIST_50K; ++outerListKey) {
189             final DataTreeModification modification = snapshot.newModification();
190             modification.write(OUTER_LIST_50K_PATHS[outerListKey], OUTER_LIST_TWO_ITEM_INNER_LIST[outerListKey]);
191             datastore.validate(modification);
192             final DataTreeCandidate candidate = datastore.prepare(modification);
193             datastore.commit(candidate);
194         }
195     }
196
197     @Benchmark
198     @Warmup(iterations = 10, timeUnit = TimeUnit.MILLISECONDS)
199     @Measurement(iterations = 20, timeUnit = TimeUnit.MILLISECONDS)
200     public void write10KSingleNodeWithTenInnerItemsInOneCommitBenchmark() throws Exception {
201         final DataTreeSnapshot snapshot = datastore.takeSnapshot();
202         final DataTreeModification modification = snapshot.newModification();
203         for (int outerListKey = 0; outerListKey < OUTER_LIST_10K; ++outerListKey) {
204             modification.write(OUTER_LIST_10K_PATHS[outerListKey], OUTER_LIST_TEN_ITEM_INNER_LIST[outerListKey]);
205         }
206         datastore.validate(modification);
207         final DataTreeCandidate candidate = datastore.prepare(modification);
208         datastore.commit(candidate);
209     }
210
211     @Benchmark
212     @Warmup(iterations = 10, timeUnit = TimeUnit.MILLISECONDS)
213     @Measurement(iterations = 20, timeUnit = TimeUnit.MILLISECONDS)
214     public void write10KSingleNodeWithTenInnerItemsInCommitPerWriteBenchmark() throws Exception {
215         final DataTreeSnapshot snapshot = datastore.takeSnapshot();
216         for (int outerListKey = 0; outerListKey < OUTER_LIST_10K; ++outerListKey) {
217             final DataTreeModification modification = snapshot.newModification();
218             modification.write(OUTER_LIST_10K_PATHS[outerListKey], OUTER_LIST_TEN_ITEM_INNER_LIST[outerListKey]);
219             datastore.validate(modification);
220             final DataTreeCandidate candidate = datastore.prepare(modification);
221             datastore.commit(candidate);
222         }
223     }
224 }