1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.analysis
.timing
.core
.tests
.store
;
12 import static org
.junit
.Assert
.assertNotNull
;
14 import java
.text
.DecimalFormat
;
15 import java
.text
.Format
;
16 import java
.util
.Arrays
;
17 import java
.util
.Random
;
19 import org
.eclipse
.jdt
.annotation
.NonNull
;
20 import org
.eclipse
.tracecompass
.internal
.segmentstore
.core
.arraylist
.ArrayListStore
;
21 import org
.eclipse
.tracecompass
.internal
.segmentstore
.core
.arraylist
.LazyArrayListStore
;
22 import org
.eclipse
.tracecompass
.internal
.segmentstore
.core
.treemap
.TreeMapStore
;
23 import org
.eclipse
.tracecompass
.segmentstore
.core
.BasicSegment
;
24 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegment
;
25 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegmentStore
;
26 import org
.junit
.FixMethodOrder
;
27 import org
.junit
.Test
;
28 import org
.junit
.runner
.RunWith
;
29 import org
.junit
.runners
.MethodSorters
;
30 import org
.junit
.runners
.Parameterized
;
31 import org
.junit
.runners
.Parameterized
.Parameters
;
34 * Segmentstore benchmarks, tests the performance for loads and reads.
36 * NOTE : Do not add this to isTracecompassFastYet, it is not information that
37 * is interesting for users, it is for developpers.
41 * @author Matthew Khouzam
44 @FixMethodOrder(MethodSorters
.NAME_ASCENDING
)
45 @RunWith(Parameterized
.class)
46 public class SegmentStoreBenchmark
{
48 private final ISegmentStore
<@NonNull ISegment
> fSegStore
;
49 private final String fName
;
50 private static final Format FORMAT
= new DecimalFormat("###,###.##"); //$NON-NLS-1$
53 * @return The arrays of parameters
55 @Parameters(name
= "{index}: {0}")
56 public static Iterable
<Object
[]> getParameters() {
57 return Arrays
.asList(new Object
[][] {
58 { "Array list store", new ArrayListStore
<>() },
59 { "Lazy array list store", new LazyArrayListStore
<>() },
60 { "Treemap store", new TreeMapStore
<>() },
68 * The name of this test
70 * The segment store to fill for the benchmarks
72 public SegmentStoreBenchmark(String name
, ISegmentStore
<@NonNull ISegment
> segStore
) {
78 * Add elements in order
81 public void test1AddInOrder() {
84 run(size
, fuzz
, new Object() {
85 }.getClass().getEnclosingMethod().getName());
89 * Add elements almost in order, this represents a typical degenerate use
93 public void test2AddFuzzyOrder() {
95 int[] fuzz
= new int[size
];
96 Random rng
= new Random(10);
97 for (int i
= 0; i
< size
; i
++) {
98 fuzz
[i
] = rng
.nextInt(1000);
100 String name
= new Object() {
101 }.getClass().getEnclosingMethod().getName();
103 run(size
, fuzz
, name
);
107 * Add elements almost in order, this represents a typical degenerate use
108 * case, then iterate over the list.
111 public void test3AddFuzzyOrderThenIterate() {
113 int[] fuzz
= new int[size
];
114 Random rng
= new Random(10);
115 for (int i
= 0; i
< size
; i
++) {
116 fuzz
[i
] = rng
.nextInt(1000);
118 String name
= new Object() {
119 }.getClass().getEnclosingMethod().getName();
121 runIterate(size
, fuzz
, name
);
125 * Add elements almost in order, this represents a typical degenerate use
126 * case, and iterate while building then when done.
129 public void test4AddFuzzyOrderThenIterateThenAddThenIterate() {
131 int[] fuzz
= new int[size
];
132 Random rng
= new Random(10);
133 for (int i
= 0; i
< size
; i
++) {
134 fuzz
[i
] = rng
.nextInt(1000);
136 String name
= new Object() {
137 }.getClass().getEnclosingMethod().getName();
139 runIterateAddIterate(size
, fuzz
, name
);
143 * Test adding elements in a random order, this is an atypical degenerate
147 public void test5AddRandomOrder() {
149 int[] fuzz
= new int[size
];
150 Random rng
= new Random(10);
151 for (int i
= 0; i
< size
; i
++) {
152 fuzz
[i
] = Math
.abs(rng
.nextInt());
154 String name
= new Object() {
155 }.getClass().getEnclosingMethod().getName();
157 runIterate(size
, fuzz
, name
);
161 * Test adding elements in a random order then iterate over the list, this
162 * is an atypical degenerate use case.
165 public void test6AddRandomOrderThenIterate() {
167 int[] fuzz
= new int[size
];
168 Random rng
= new Random(10);
169 for (int i
= 0; i
< size
; i
++) {
170 fuzz
[i
] = Math
.abs(rng
.nextInt());
172 String name
= new Object() {
173 }.getClass().getEnclosingMethod().getName();
175 runIterate(size
, fuzz
, name
);
179 * Test adding elements in a random order then iterate over the list then
180 * add more then iterate again, this is an atypical degenerate use case.
183 public void test7AddRandomOrderThenIterateThenAddThenIterate() {
185 int[] fuzz
= new int[size
];
186 Random rng
= new Random(10);
187 for (int i
= 0; i
< size
; i
++) {
188 fuzz
[i
] = rng
.nextInt(1000);
190 String name
= new Object() {
191 }.getClass().getEnclosingMethod().getName();
193 runIterateAddIterate(size
, fuzz
, name
);
196 private void run(int size
, int[] fuzz
, String method
) {
197 long duration
= populate(size
, fuzz
, fSegStore
);
198 outputResults(duration
, method
);
201 private static long populate(int size
, int[] fuzz
, ISegmentStore
<@NonNull ISegment
> store
) {
203 long start
= System
.nanoTime();
204 populate(size
, fuzz
, store
, 1000000);
205 long end
= System
.nanoTime();
209 private void runIterate(int size
, int[] fuzz
, String method
) {
210 long duration
= addAndIterate(size
, fuzz
, fSegStore
);
212 outputResults(duration
, method
);
215 private static long addAndIterate(int size
, int[] fuzz
, ISegmentStore
<@NonNull ISegment
> store
) {
216 long start
= System
.nanoTime();
217 populate(size
, fuzz
, store
);
219 long end
= System
.nanoTime();
223 private void runIterateAddIterate(int size
, int[] fuzz
, String method
) {
224 long duration
= runIterateAddIterate(size
, fuzz
, fSegStore
);
225 outputResults(duration
, method
);
228 private static long runIterateAddIterate(int size
, int[] fuzz
, ISegmentStore
<@NonNull ISegment
> store
) {
230 long start
= System
.nanoTime();
231 for (int i
= 0; i
< 50000; i
++) {
232 long startTime
= i
+ fuzz
[i
% size
];
233 store
.add(new BasicSegment(startTime
, startTime
+ 10));
236 for (int i
= 50000; i
< 100000; i
++) {
237 long startTime
= i
+ fuzz
[i
% size
];
238 store
.add(new BasicSegment(startTime
, startTime
+ 10));
241 long end
= System
.nanoTime();
245 private static Object
iterate(ISegmentStore
<@NonNull ISegment
> store
) {
246 Object shutupCompilerWarnings
= null;
247 for (ISegment elem
: store
) {
248 shutupCompilerWarnings
= elem
;
250 return shutupCompilerWarnings
;
253 private static void populate(int size
, int[] fuzz
, ISegmentStore
<@NonNull ISegment
> store
, int count
) {
254 for (int i
= 0; i
< count
; i
++) {
255 long start
= i
+ fuzz
[i
% size
];
256 store
.add(new BasicSegment(start
, start
+ 10));
260 private void outputResults(long duration
, String method
) {
261 System
.out
.println(fName
+ ": Time taken for test " + method
+ ": " + FORMAT
.format(duration
));