Commit | Line | Data |
---|---|---|
2b408e85 AM |
1 | /* |
2 | * Copyright (C) 2015, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com> | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along | |
15 | * with this program; if not, write to the Free Software Foundation, Inc., | |
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
17 | */ | |
18 | ||
da8308fe | 19 | package org.lttng.ust.agent.benchmarks.jul.handler; |
7ac7128a AM |
20 | |
21 | import java.util.LinkedList; | |
22 | import java.util.List; | |
23 | import java.util.logging.Handler; | |
24 | import java.util.logging.Level; | |
25 | import java.util.logging.Logger; | |
26 | ||
7a4f0255 MJ |
27 | import org.junit.jupiter.api.AfterEach; |
28 | import org.junit.jupiter.api.BeforeEach; | |
9db2c69a | 29 | import org.junit.jupiter.api.Tag; |
7a4f0255 MJ |
30 | import org.junit.jupiter.api.Test; |
31 | import org.junit.jupiter.api.extension.ExtendWith; | |
32 | import org.lttng.ust.agent.utils.TestPrintExtension; | |
7ac7128a | 33 | |
8a0613fa AM |
34 | /** |
35 | * Base abstract class for JUL benchmarks. Sub-classes can setup parameters to | |
36 | * test different types of log handlers. | |
37 | */ | |
7a4f0255 | 38 | @ExtendWith(TestPrintExtension.class) |
9db2c69a MJ |
39 | @Tag("agent:jul") |
40 | @Tag("domain:jul") | |
41 | @Tag("benchmark") | |
d4e2e87c | 42 | public abstract class JulHandlerBenchmarkBase { |
7ac7128a AM |
43 | |
44 | // ------------------------------------------------------------------------ | |
45 | // Configurable test parameters | |
46 | // ------------------------------------------------------------------------ | |
47 | ||
48 | /** Nb of runs per test, result will be averaged */ | |
49 | private static final int NB_RUNS = 10; | |
50 | ||
51 | /** Trace/log events per run */ | |
52 | private static final int NB_ITER = 100000; | |
53 | ||
54 | /** Which tests to run (for different number of threads) */ | |
55 | private static final int[] NB_THREADS = {1, 1, 2, 3, 4, 5, 6, 7, 8}; | |
56 | ||
57 | // ------------------------------------------------------------------------ | |
58 | // Attributes | |
59 | // ------------------------------------------------------------------------ | |
60 | ||
86316987 | 61 | protected Logger logger; |
7ac7128a AM |
62 | protected Handler handler; |
63 | ||
64 | // ------------------------------------------------------------------------ | |
65 | // Maintenance methods | |
66 | // ------------------------------------------------------------------------ | |
67 | ||
8a0613fa AM |
68 | /** |
69 | * Base test setup | |
70 | */ | |
7a4f0255 | 71 | @BeforeEach |
7ac7128a AM |
72 | public void setup() { |
73 | /* Set up the logger */ | |
74 | logger = Logger.getLogger("Test logger"); | |
75 | logger.setUseParentHandlers(false); | |
76 | logger.setLevel(Level.ALL); | |
77 | ||
78 | /* Sub-classes' @Before will setup the Handler */ | |
79 | } | |
80 | ||
8a0613fa AM |
81 | /** |
82 | * Base test teardown | |
83 | */ | |
7a4f0255 | 84 | @AfterEach |
7ac7128a | 85 | public void teardown() { |
7ac7128a | 86 | if (handler != null) { |
86316987 | 87 | logger.removeHandler(handler); |
7ac7128a AM |
88 | handler.close(); |
89 | } | |
90 | handler = null; | |
91 | logger = null; | |
92 | } | |
93 | ||
94 | // ------------------------------------------------------------------------ | |
95 | // Test methods | |
96 | // ------------------------------------------------------------------------ | |
97 | ||
8a0613fa AM |
98 | /** |
99 | * Main test class for running the benchmark | |
100 | */ | |
7ac7128a AM |
101 | @Test |
102 | public void runBenchmark() { | |
249f8797 | 103 | if (logger != null && handler != null) { |
7ac7128a AM |
104 | logger.addHandler(handler); |
105 | } | |
106 | ||
107 | System.out.println(); | |
108 | System.out.println("Running benchmark: " + this.getClass().getCanonicalName()); | |
109 | for (int i : NB_THREADS) { | |
110 | runTest(logger, i); | |
111 | } | |
112 | } | |
113 | ||
114 | private static void runTest(Logger log, int nbThreads) { | |
249f8797 | 115 | long total = 0; |
7ac7128a AM |
116 | for (int i = 0; i < NB_RUNS; i++) { |
117 | Runner runner = new Runner(nbThreads, NB_ITER, log); | |
118 | ||
249f8797 | 119 | long start = System.nanoTime(); |
7ac7128a | 120 | runner.run(); |
249f8797 | 121 | long end = System.nanoTime(); |
7ac7128a AM |
122 | |
123 | total += (end - start); | |
124 | } | |
249f8797 AM |
125 | long average = (total / NB_RUNS); |
126 | System.out.println(nbThreads + " threads, average = " + average / NB_ITER + " ns/loop"); | |
7ac7128a AM |
127 | } |
128 | ||
129 | // ------------------------------------------------------------------------ | |
130 | // Helper classes | |
131 | // ------------------------------------------------------------------------ | |
132 | ||
133 | private static class Runner implements Runnable { | |
134 | ||
135 | private final List<Worker> workers = new LinkedList<>(); | |
136 | private final List<Thread> workerThreads = new LinkedList<>(); | |
137 | ||
138 | public Runner(int nbThreads, int nbIter, Logger log) { | |
139 | ||
140 | for (int id = 0; id < nbThreads; id++) { | |
141 | Worker curWorker = new Worker(id, nbIter, log); | |
142 | workers.add(curWorker); | |
143 | workerThreads.add(new Thread(curWorker, "worker " + id)); | |
144 | } | |
145 | } | |
146 | ||
147 | @Override | |
148 | public void run() { | |
249f8797 | 149 | workerThreads.forEach(Thread::start); |
7ac7128a | 150 | |
249f8797 | 151 | workerThreads.forEach(t -> { |
7ac7128a | 152 | try { |
249f8797 | 153 | t.join(); |
7ac7128a AM |
154 | } catch (InterruptedException e) { |
155 | e.printStackTrace(); | |
156 | } | |
249f8797 | 157 | }); |
7ac7128a AM |
158 | } |
159 | ||
160 | private static class Worker implements Runnable { | |
161 | ||
162 | private final Logger log; | |
163 | private final int threadId; | |
164 | private final int nbIter; | |
165 | ||
249f8797 AM |
166 | @SuppressWarnings("unused") |
167 | private volatile int value = 0; | |
168 | ||
7ac7128a AM |
169 | public Worker(int threadId, int nbIter, Logger log) { |
170 | this.log = log; | |
171 | this.threadId = threadId; | |
172 | this.nbIter = nbIter; | |
173 | } | |
174 | ||
175 | @Override | |
176 | public void run() { | |
177 | for (int i = 0; i < nbIter; i++) { | |
249f8797 AM |
178 | value = i; |
179 | if (log != null) { | |
180 | log.info("Thread " + threadId + ", iteration " + i); | |
181 | } | |
7ac7128a AM |
182 | } |
183 | } | |
7ac7128a AM |
184 | } |
185 | } | |
186 | } |