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 singleNodes100KWriteBenchmark() throws Exception {
145         applyWriteSingleNode(OUTER_LIST_100K);
146     }
147
148     private void applyWriteSingleNode(final int reps) throws DataValidationFailedException {
149         final DataTreeSnapshot snapshot = datastore.takeSnapshot();
150         final DataTreeModification modification = snapshot.newModification();
151         for (int outerListKey = 0; outerListKey < reps; ++outerListKey) {
152             modification.write(OUTER_LIST_100K_PATHS[outerListKey], OUTER_LIST_ONE_ITEM_INNER_LIST[outerListKey]);
153         }
154         datastore.validate(modification);
155         final DataTreeCandidate candidate = datastore.prepare(modification);
156         datastore.commit(candidate);
157     }
158
159     @Benchmark
160     @Warmup(iterations = 10, timeUnit = TimeUnit.MILLISECONDS)
161     @Measurement(iterations = 20, timeUnit = TimeUnit.MILLISECONDS)
162     public void twoNodes50KWriteBenchmark() throws Exception {
163         applyWriteTwoNodes(OUTER_LIST_50K);
164     }
165
166     private void applyWriteTwoNodes(final int reps) throws DataValidationFailedException {
167         final DataTreeSnapshot snapshot = datastore.takeSnapshot();
168         final DataTreeModification modification = snapshot.newModification();
169         for (int outerListKey = 0; outerListKey < reps; ++outerListKey) {
170             modification.write(OUTER_LIST_50K_PATHS[outerListKey], OUTER_LIST_TWO_ITEM_INNER_LIST[outerListKey]);
171         }
172         datastore.validate(modification);
173         final DataTreeCandidate candidate = datastore.prepare(modification);
174         datastore.commit(candidate);
175     }
176
177     @Benchmark
178     @Warmup(iterations = 10, timeUnit = TimeUnit.MILLISECONDS)
179     @Measurement(iterations = 20, timeUnit = TimeUnit.MILLISECONDS)
180     public void tenNodes10KWriteBenchmark() throws Exception {
181         applyWriteTenNodes(OUTER_LIST_10K);
182     }
183
184     private void applyWriteTenNodes(final int reps) throws DataValidationFailedException {
185         final DataTreeSnapshot snapshot = datastore.takeSnapshot();
186         final DataTreeModification modification = snapshot.newModification();
187         for (int outerListKey = 0; outerListKey < reps; ++outerListKey) {
188             modification.write(OUTER_LIST_10K_PATHS[outerListKey], OUTER_LIST_TEN_ITEM_INNER_LIST[outerListKey]);
189         }
190         datastore.validate(modification);
191         final DataTreeCandidate candidate = datastore.prepare(modification);
192         datastore.commit(candidate);
193     }
194 }